有多种选择。
您不必operator bool
在类中实现重载。
而且它通常不是最好的选择。
最佳:命名状态检查。
最好的方法是使用命名的状态检查方法。例如,iostreams 有fail
成员,这样你就可以写
while( !cin.fail() ) { ... }
对于您自己的课程,它可能如下所示:
struct S
{
bool is_good() const { return ...; } // Whatever name.
};
马马虎虎:explicit
转换为bool
.
下一个最好的是explicit
转换运算符。拥有它explicit
可以防止 if 因将您的对象之一作为函数参数传递而被无意调用。条件中仍使用explicit
转换运算符,因此您可以编写例如
while( cin ) { ... }
在 C++11 中调用一个
explicit operator bool () const { return !fail(); }
对于您自己的课程,它看起来像
struct S
{
explicit operator bool () const { return ...; }
};
不好:隐式转换为“私有”指针类型。
第三,如果您使用的是不支持explicit
转换的编译器,即 C++03 编译器,并且由于某些莫名其妙的原因您不希望命名检查是最佳选择,那么您可以选择一个结果类型最大程度地减少意外呼叫的机会。
在 C++03 中,iostreams 使用隐式转换为void*
(而不是 to bool
)。
有些人提倡使用“安全布尔惯用语”,其结果是指向客户端代码无法访问的 C++03 类型的指针。
绝对最糟糕:隐式转换为bool
.
最糟糕的选择就像
struct S
{
operator bool () { return ... }
};
有了这个
从调用代码中看不到正在检查什么条件。
运算符可能会因传递S
as 函数参数而被无意调用。
不能在const
对象上调用转换。
添加 aconst
只会让它稍微不那么糟糕。
它仍然非常糟糕。:-)