首页 > 解决方案 > C ++:使用重载显式运算符bool的类

问题描述

语境:

我有一个具有内部布尔值的类,它似乎是重载运算符 bool的一个很好的候选者,如下所示:

class MyBool{

    private:
    bool value_ = false;

    // Nice API and logic to set the interal value_ to true or false...

    public: 
    explicit operator bool() const {
        return value_;
    };

};

https://en.cppreference.com/w/cpp/language/implicit_conversion,“上下文转换”部分,这适用于:

这就解释了为什么我在尝试以其他方式使用它时会出错,如下所示:

MyBool x;  
///...
bool y = x; // --> error: cannot convert ‘MyBool’ to ‘bool’ in initialization 
// or:
bool z; 
z = x;      // --> error: cannot convert ‘MyBool’ to ‘bool’ in assignment

// Or returning from a function:
bool func(...){
     MyBool x;
     // ...
     return x; // --> error: cannot convert ‘MyBool’ to ‘bool’ in return
}

// Or in Gtests, like:
MyBool x;
// ...
EXPECT_TRUE(x); // --> error: no matching function for call to ‘testing::AssertionResult::AssertionResult(MyBool)’

如果我删除了显式关键字,由于隐式转换会出现一些问题(C++ 11 之前的安全布尔成语:http: //blog.asymptotic.co.uk/2014/03/the-safe-bool-idiom-在-c/ )。

在这些情况下,我可以将MyBool变量显式转换为 bool 并且它会起作用,但对我来说,这种非同质使用类型违背了重载运算符的目的,即:能够自然地将MyBool用作 bool . 相反,我可以像这样添加一个成员函数:

bool get_value() const {
    return value_;
}

并在每次我需要“强制转换”为布尔时使用 x.get_value(),即使在条件、循环等中也是如此。

问题是:有没有办法在上述情况下使用这个类,或者其中一些,只修改类代码(不是调用代码),而不删除显式关键字?(最好在 C++11 中)。

标签: c++c++11

解决方案


问题似乎是如何(1)隐式转换为 bool 和(2)避免整数提升/转换。删除转换为int

class MyBool
{
public: 
    operator bool() const
    {
        return value_;
    };

    operator int() const = delete;

private:
    bool value_ = false;
};

问题中的所有行现在都可以编译,因为允许隐式转换。由于删除了整数转换,因此没有任何安全布尔问题编译:

MyBool x;
int i = x;
x << 1;
x < 1;

推荐阅读