以下行为的原因是什么?
class BoolWrapper
{
public:
BoolWrapper(bool value) : value(value) {}
operator bool() const { return value; }
operator int() const { return (int) value; }
private:
bool value;
};
BoolWrapper bw(true);
if (bw) { ... } // invokes operator bool()
if (bw == true) { ... } // invokes operator int() -- why?
预计会出现这种情况吗? (使用GCC 4.7.2。)
答案 0 :(得分:6)
从5月9日开始:
许多期望算术或算术操作数的二元运算符 枚举类型导致转换并产生类似的结果类型 办法。目的是产生一种普通类型,它也是一种类型 结果。这种模式称为通常的算术转换, 其定义如下:
[一些浮点项无关紧要。]
否则,应对两者进行整体促销(4.5) 操作数。
从3.9.1 / 6开始,我们看到bool有资格进行整体晋升:
bool类型的值为true或false.42)[注意:没有 signed,unsigned,short或long bool类型或值。 ]如上所述 在下面,bool值表现为整数类型。 bool类型的值 参加整体促销活动(4.5)。
答案 1 :(得分:6)
您的期望是基于您的信念,即语言已经知道如何比较两个bool
值。实际上它并没有,但不管它听起来多么令人惊讶。更确切地说,语言"不知道"怎么做直接。
在概念层面,C ++没有用于bool vs. bool
比较的专用内置等式比较运算符。即使您在代码中编写true == false
,它也会被语言解释为(int) true == (int) false
。隐式转换为int
是由通常的算术转换的规则引入的,之后使用int vs. int
比较。
可以比较两个bool
值的最直接的内置运算符是用于int vs. int
比较的运算符。这是编译器在您的情况下尝试使用的运算符。同一个运算符将用于char vs. char
和short vs. short
比较。
换句话说,编译器在bool
表达式中使用bw == true
转换运算符的唯一方法就是
(int)(bool) bw == (int) true
这当然不是最佳的"比直接
(int) bw == (int) true
这是驱动语言选择后一种变体的逻辑。
答案 2 :(得分:4)
在第一种情况下,if
子句需要bool
条件,因此这是选定的转换。
在第二种情况下,您要求对BoolWrapper
和bool
进行比较。由于不存在operator ==
重载,编译器必须将这些参数转换为合适的参数。根据标准(第4.5节,整体促销),转换的首选整数类型为int
。由于BoolWrapper
和bool
都可以转换为int
,因此这是选定的转化。