nya*_*108 15 c++ if-statement switch-statement conversion-operator explicit-conversion
为什么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 **/ }
}
Run Code Online (Sandbox Code Playgroud)
编译错误是switch quantity is not an integer在if声明中它被完美地识别为a bool.(GCC)
Clo*_*onk 17
语法是switch ( condition ) statement与
condition - 整数或枚举类型的任何表达式,或者上下文可 隐式转换为整数或枚举类型的类类型的表达式,或者使用大括号或等于初始化程序的此类型的单个非数组变量的声明.
这意味着您只能对整数或枚举类型执行切换操作.为了使编译器能够隐式地将Wrapper转换为整数/枚举类型,您需要删除显式关键字:
显式说明符指定构造函数或转换函数(自C++ 11以来)不允许隐式转换
您还可以将Wrapper转换为int类型.
编辑地址@ acraig5075备注:
您必须小心哪个运算符是显式的,哪个是隐式的.如果两者都是隐式的,代码将无法编译,因为会有一个不确定性:
struct Wrapper
{
operator int() { return 0; }
operator bool() { return true; }
};
Run Code Online (Sandbox Code Playgroud)
source_file.cpp:在函数'int main()'中:source_file.cpp:12:14:
错误:来自'Wrapper'的模糊默认类型转换
开关(w){
^ source_file.cpp:12:14:注意:候选转换
包括'Wrapper :: operator int()'和'Wrapper :: operator bool()'
消除歧义的唯一方法是进行演员表演.
如果只有一个运算符是显式的,则另一个运算符将被选择用于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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
if is true
case 1
Run Code Online (Sandbox Code Playgroud)
w已被隐式转换为1(true)(因为operator int是显式的)并且执行了case 1.
另一方面 :
struct Wrapper
{
operator int() { return 0; }
explicit operator bool() { return true; }
};
Run Code Online (Sandbox Code Playgroud)
输出:
if is true
case 0
Run Code Online (Sandbox Code Playgroud)
w已被隐式转换为0因为运算符bool是显式的.
在这两种情况下,if语句都为true,因为在if语句内部对boolean w进行了上下文计算.
Mar*_*ara 10
我认为这解释了为什么switch声明不被接受,而if声明是:
在以下五个上下文中,预期类型为bool,如果声明
bool t(e);格式正确,则构建隐式转换序列.也就是说,考虑显式的用户定义转换函数explicit T::operator bool() const;.这种表达e被认为是在语境上可转换为bool.