11

以下行为的原因是什么?

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。)

4

3 回答 3

6

从 5/9 开始:

许多期望算术或枚举类型的操作数的二元运算符会以类似的方式导致转换和产生结果类型。目的是产生一个通用类型,这也是结果的类型。这种模式称为通常的算术转换,其定义如下:

[一些无关紧要的浮点项目。]

否则,应在两个操作数上执行积分提升 (4.5)。

从 3.9.1/6 开始,我们看到 bool 有资格进行积分提升:

bool 类型的值为真或假。42) [注意:没有带符号、无符号、短或长布尔类型或值。] 如下所述,布尔值表现为整数类型。bool 类型的值参与积分促销 (4.5)。

于 2012-11-06T16:12:53.877 回答
6

您的期望基于您的信念,即语言已经知道如何比较两个bool值。实际上并没有,无论听起来多么令人惊讶。更准确地说,语言“不知道”如何直接做到这一点。

在概念级别,C++ 没有专门的内置相等比较运算符用于bool vs. bool比较。即使您true == false在代码中编写代码,它实际上也被语言解释为(int) true == (int) false. 隐式转换int通常的算术转换规则引入,然后int vs. int使用比较。

bool可以比较两个值的最直接的内置运算符是用于int vs. int比较的运算符。这也是编译器在您的情况下尝试使用的运算符。相同的运算符将用于char vs. charshort vs. short比较。

换句话说,编译器可以在表达式中使用bool转换运算符的唯一方法是bw == true

(int)(bool) bw == (int) true

这肯定不如直接“最佳”

(int) bw == (int) true

这是驱动语言选择后一种变体的逻辑。

于 2012-11-06T16:33:25.977 回答
4

在第一种情况下,if子句需要一个bool条件,因此这是选定的转换。

在第二种情况下,您要求比较 aBoolWrapper和 a bool。由于不operator ==存在重载来执行此操作,因此编译器必须将这些参数转换为合适的参数。根据标准(第 4.5 节,积分促销),转换的首选积分类型是int. 由于两者BoolWrapperbool都可以转换为int,因此这是选定的转换。

于 2012-11-06T16:13:05.180 回答