当对象同时提供“运算符!”和“运算符布尔”时,在表达式“!obj”中使用

When an object provides both `operator!` and `operator bool`, which is used in the expression `!obj`?

本文关键字:运算符 表达式 obj 布尔 对象 运算符布尔      更新时间:2023-10-16

我遇到了一个我自己无法回答的问题。另外,我在谷歌和这里都没有找到答案。比如说,我想在 if 子句中"检查对象的有效性",如下所示:

MyClass myObject;
// [some code, if any]
if (!myObject)
{
    // [do something]
}

让我们MyClass

定义如下:
class MyClass
{
public:
    MyClass() { };
    virtual ~MyClass() { };
    bool operator!()
    {
        return !myBool;
    };
    operator bool()
    {
        return myBool;
    };
private:
    bool myBool = 0;
};

我现在的问题是:在这个 if 子句中实际使用了哪个重载运算符?无论哪种方式,结果显然都是一样的。

它将使用operator! .

选择其参数类型与参数匹配的函数将优先于需要类型转换的函数。

你会发现operator !被执行,因为它是最直接的分辨率。如果它改用operator bool,那么它必须首先调用转换运算符,然后将!分别应用于该运算符。

作为一般规则,最好避免这种情况。通常,最好只定义bool转换,因为严格来说,这是您希望逻辑运算符执行的操作,而不是直接MyClass。定义两者会产生一些可读性问题,并且是一种冗余代码重复的形式(这可能会导致将来的程序员错误)。