Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:使用带有显式运算符bool重载的类_C++_C++11 - Fatal编程技术网

C++ C++;:使用带有显式运算符bool重载的类

C++ C++;:使用带有显式运算符bool重载的类,c++,c++11,C++,C++11,上下文: 我有一个具有内部布尔值的类,它似乎很适合重载运算符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_; }; }

上下文:

我有一个具有内部布尔值的类,它似乎很适合重载运算符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_;
    };

};
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)’
bool get_value() const {
    return value_;
}
在“上下文转换”部分中,此功能适用于:

  • if、while、for的控制表达
  • 内置逻辑运算符的操作数!、&&和| |
  • 条件运算符的第一个操作数?:
  • 静态断言声明中的谓词
  • noexcept说明符中的表达式
这就解释了为什么我在尝试以其他方式使用它时会出现错误,例如:

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_;
    };

};
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)’
bool get_value() const {
    return value_;
}
如果我删除了explicit关键字,由于隐式转换(C++11之前版本中的safe-bool习惯用法:)会出现一些问题

在这些情况下,我可以显式地将MyBool变量强制转换为bool,这会起作用,但对我来说,这种非齐次使用有点违背了重载操作符的目的,即:能够自然地将MyBool用作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_;
    };

};
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)’
bool get_value() const {
    return value_;
}
每次我需要对bool进行“强制转换”时,都要使用x.get_value(),即使在条件、循环等中也是如此

问题是:是否有办法在上述情况下或其中一些情况下使用此类,只修改类代码(而不是调用代码),而不删除显式关键字?
(最好是在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;
myboolx;
int i=x;

xC++20删除所有转换运算符的版本,这些运算符将隐式转换为bool:

#include <concepts>

class MyBool
{
private:
    bool value_ = false;

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

    template <std::convertible_to<bool> T>
    operator T() = delete;
};
#包括
MyBool类
{
私人:
布尔值=假;
公众:
显式运算符bool()常量{返回值};
模板
运算符T()=删除;
};

在我看来,您似乎希望对
MyBool
进行隐式转换。在哪些情况下不需要隐式转换?不能使用
explicit
关键字进行隐式转换。如果你想保持
的明确性
,那就做
(bool)x
很好,谢谢。似乎类似于@Jeff Garret的答案。不过,我使用的是C++11(我对问题进行了相应的编辑)。谢谢,工作正常。WRT@bolov answer,似乎禁止隐式转换为int,但没有其他类型,因此这是否可能仍然会产生一些意外后果(通过显式方法可以避免)?@Milo如果您尝试转换为另一个整数类型(如
long
short
),您会得到一个“转换是不明确的”错误。不是相关的错误消息,但至少它是一个错误。从
MyBool
到非
bool
的隐式转换,非
int
整数类型
T
可以使用用户定义的到
bool
的转换,然后是到
T
的整数转换,或者用户定义的到
int
的转换,然后是到
T
的积分转换。这两个都不好,所以它是不明确的。也可以在C++11中使用转换运算符(更好的错误消息“use of deleted function”,但可能更难正确执行):
template operator T()const=delete
@bolov的答案将相当于SFINAE对
std::is_convertible
。它与SFINAE的不同之处在于,它不允许转换为本身可转换为
bool
(例如,
OtherBool
)的类型,从而使其与
std::is_算术
operator int=delete
不同。这不会直接导致安全的BoOL问题,因为C++将不隐式地组合两个用户定义的转换。这两个答案都有自己的位置。