逻辑操作员执行顺序

Logical operator execution order

本文关键字:顺序 执行 操作员      更新时间:2023-10-16

我有关于操作员的超载,并带有有趣的代码:

#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。对于下降者和其他认为我不能自己执行此代码的人。我可以。我做到了。我已经改变了很多次,以查看其行为。所以呢?这不是解释。我已经要求参考哪些明确说明该代码遵守的规则。它在我的计算机上工作的信息不会回答这个问题 - 如果这甚至在不同环境(OS,也许是处理器等)上都无法移植怎么办?

它的工作方式很简单。编译器解析源并看到if(!a)。然后检查A是否定义了operator!。只是碰巧这样做。这样就被称为。

如果它已经看到if(a),它将检查A可转换为可以在if条件下使用的东西。碰巧的是,它确实是可转换的。

如果没有operator!,则编译器会检查A是否可以转换为可能在逻辑上被否定的东西。然后将进行转换为布尔。


顺便说一句,即使在令人惊讶的地方,转换也会发生。例如a + 1将编译。我认为不是我们想要的。最好只能在bool的上下文中允许它。您可以通过标记转换运算符的明确说明来做到这一点:
explicit operator bool() {
    return true;
}

!a不超过a.operator!()的句法糖,您已经定义了:这是编译器的首选选择。

因此,转换为bool操作员从来都不是候选人。

您可以通过写作

来考虑后者
if (!(bool)a) {