以下行为的原因是什么?
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。)
您的期望是基于您的信念,即语言已经知道如何比较两个 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
这是驱动语言选择后一种变体的逻辑。
从5/9开始:
许多二进制运算符,它们期望算术运算或运算
枚举类型导致转换并产生类似的结果类型
办法。目的是产生一种普通类型,它也是一种类型
结果。这种模式称为通常的算术转换,
其定义如下:
[一些无关紧要的浮点项目。]
否则,应对两者进行整体促销(4.5)
操作数。
从3.9.1 / 6我们看到bool有资格进行整体推广:
bool类型的值为true或false.42)[注意:没有
signed,unsigned,short或long bool类型或值。 ]如上所述
在下面,bool值表现为整数类型。 bool类型的值
参加整体促销活动(4.5)。
在第一种情况下,一个 if
条款期望a bool
条件,所以这是选定的转换。
在第二种情况下,您要求在a之间进行比较 BoolWrapper
和a bool
。从没有 operator ==
如果存在重载,编译器必须将这些参数转换为合适的参数。根据标准(第4.5节, 整体促销),转换的首选整数类型是 int
。既然都是 BoolWrapper
和 bool
可以转换为 int
,这是选定的转换。