逻辑运算符执行顺序

时间:2017-09-26 14:22:09

标签: c++

我有关于运算符重载的问题,并附带了一个有趣的代码:

#include <iostream>

class A {
public:
    operator bool() {
        return true;
    }

    bool operator!() {
        return false;
    }
};

int main() {
    A a;

    if (!a) {
        std::cout << "HELLO";
    } else {
        std::cout << "WORLD";
    }
    std::cout << std::endl;

    return 0;
}

首先会叫什么,之后会怎样?为什么?这是在cppreference中的任何地方描述的吗?

P.S。对于那些认为我自己无法执行此代码的downvoters和其他人。我可以。我做到了。我已经多次改变它以查看它的行为。所以呢?这不是解释。我已经要求提供一个明确的参考,说明此代码遵循的规则。它在我的机器上如何工作的信息没有回答这个问题 - 如果这甚至不能在不同环境(操作系统,可能是处理器等)中移植,该怎么办?

2 个答案:

答案 0 :(得分:7)

它的工作原理很简单。编译器解析源并看到if(!a)。然后,它会检查A是否定义了operator!。就是这样。因此被调用。

如果看到if(a),则会检查A是否可以转换为可以在if条件下使用的内容。碰巧它确实可以转换。

如果没有operator!,则编译器会检查A是否可以转换为可能在逻辑上否定的内容。 然后将执行转换为bool。

顺便说一下,即使在令人惊讶的地方也会发生转换。例如a + 1将编译。我认为不是我们想要的。最好只在bool符合上下文的情况下允许它。您可以通过明确标记转换运算符来实现:

explicit operator bool() {
    return true;
}

答案 1 :(得分:4)

!a只不过是您定义的a.operator!()的语法糖:这是编译器的首选。

因此转换为bool运算符绝不是候选者。

你可以通过写

来设计后者
if (!(bool)a) {