请考虑以下代码:
class Truth
{
public:
Truth(bool val) : value(val) {}
bool operator!() {std::cout<<"operator!()"<<std::endl; return !value;}
operator bool() {std::cout<<"operator bool()"<<std::endl; return value;}
private:
bool value;
};
int main()
{
Truth t(true);
if(!t)
std::cout<<"t is false"<<std::endl;
else
std::cout<<"t is true"<<std::endl;
if(!!t)
std::cout<<"t is false"<<std::endl;
else
std::cout<<"t is true"<<std::endl;
if(t)
std::cout<<"t is false"<<std::endl;
else
std::cout<<"t is true"<<std::endl;
return 0;
}
在语句if(!t)
和if(!!t)
中调用重载的operator!()
实现,而在语句if(t)
中(不是超常)调用重载的operator bool()
实现而是打来电话。
但是,如果operator!()
实现被注释掉,则在所有3个语句中都会调用operator bool()
。
我理解“为什么”会发生这种情况,但我担心的是,重载逻辑NOT运算符(!)似乎错过了一半的真值评估语义,而bool
类型转换运算符似乎很好地覆盖了它们。
我是否遗漏了某些内容,或者是否应该鼓励逻辑NOT运算符的重载以支持bool类型转换?
答案 0 :(得分:3)
在C ++ 11中,您可以简单地重载explicit operator bool()
。没有理由超过operator!
,除非你想要它做一些不同的事情 - 如果你认为你想要那样,你应该再考虑一下。
历史上,重载operator bool
会打开隐式转换为任何数字类型的大门,这可能会导致混淆,含糊不清和微妙的错误;所以最好不要这样做。如果你不想让safe bool idiom陷入困境,那么重载operator!
是一种允许在条件中使用的简单方法,无需打开那扇门。 (该链接仅用于历史利益;成语is obsolete in C++11,感谢显式转换运算符。)