c++ - 为什么 switch 和 if 语句与转换运算符的行为不同?
问题描述
为什么switch
和if
语句与转换运算符的行为不同?
struct WrapperA
{
explicit operator bool() { return false; }
};
struct WrapperB
{
explicit operator int() { return 0; }
};
int main()
{
WrapperA wrapper_a;
if (wrapper_a) { /** this line compiles **/ }
WrapperB wrapper_b;
switch (wrapper_b) { /** this line does NOT compile **/ }
}
编译错误switch quantity is not an integer
在if
语句中被完全识别为bool
. (海合会)
解决方案
语法switch ( condition ) statement
是
条件 - 整数或枚举类型的任何表达式,或上下文 隐式可转换为整数或枚举类型的类类型,或使用大括号或等号初始化器声明此类类型的单个非数组变量。
这意味着您只能在 integer 或 enum类型上执行 switch case 。为了使编译器能够将 Wrapper 隐式转换为整数/枚举类型,您需要删除显式关键字:
显式说明符指定构造函数或转换函数(C++11 起)不允许隐式转换
您还可以将 Wrapper 转换为 int 类型。
编辑地址@acraig5075 评论:
您必须小心哪个运算符是显式的,哪个是隐式的。如果两者都是隐式的,则代码将无法编译,因为会有歧义:
struct Wrapper
{
operator int() { return 0; }
operator bool() { return true; }
};
source_file.cpp:在函数“int main()”中:source_file.cpp:12:14:
错误:来自“Wrapper”的模棱两可的默认类型转换</p>
开关 (w) {
^ source_file.cpp:12:14: 注意:候选转换
包括 'Wrapper::operator int()' 和 'Wrapper::operator bool()'</p>
消除歧义的唯一方法是进行强制转换。
如果只有一个运算符是显式的,则将为 switch 语句选择另一个:
#include <iostream>
struct Wrapper
{
explicit operator int() { return 0; }
operator bool() { return true; }
};
int main()
{
Wrapper w;
if (w) { /** this line compiles **/std::cout << " if is true " << std::endl; }
switch (w) {
case 0:
std::cout << "case 0" << std::endl;
break;
case 1:
std::cout << "case 1" << std::endl;
break;
}
return 0;
}
输出 :
if is true
case 1
w
已隐式转换为1
( true
) (因为 operator int 是显式的)并执行 case 1。
另一方面 :
struct Wrapper
{
operator int() { return 0; }
explicit operator bool() { return true; }
};
输出:
if is true
case 0
w
已隐式转换为,0
因为运算符 bool 是显式的。
在这两种情况下,if 语句都为真,因为根据上下文对 if 语句内的布尔值w
进行评估。
推荐阅读
- php - Laravel 自定义命令不创建 csv
- elasticsearch - Kibana 聚合管道
- flutter - Flutter pubspec.yaml,音频播放器无法正常工作
- c++ - QUdpSocket 有时会丢失数据报
- python - 在anaconda中安装某个包的两个版本
- sapui5 - SAPUI5 - sap.m.Input:如果在正确的设备上运行,它会自动调用软(虚拟)键盘吗?
- reactjs - 使用默认值键入对象参数
- encoding - 分类变量的未知数据中的概率编码,其中目标是我们必须预测的?
- linux - Bash以确定的模式用另一个替换字符串
- python - 关于 with 语句 python 的困惑