将C++类转换为布尔值

34

对于C++的所有基本类型,可以简单地查询:

if(varname)

并且该类型被转换为布尔值以进行评估。有没有办法在用户定义的类中复制此功能?我的其中一个类由整数标识,尽管它具有许多其他成员,但我希望能够以这种方式检查整数是否设置为NULL。

谢谢。


在谷歌上搜索“安全布尔值”,你会看到不同的解决方案,允许进行布尔值评估而无需显式转换为bool类型,避免常见的转换陷阱。 - David Rodríguez - dribeas
5个回答

48

C++11的方法是:

struct Testable
  {
    explicit operator bool() const
      { return false; }
  };

int main ()
  {
    Testable a, b;
    if (a)      { /* do something  */ }  // this is correct
    if (a == b) { /* do something  */ }  // compiler error
  }

请注意 explicit 关键字,它能够防止编译器进行隐式转换。


28

您可以定义一个用户定义的转换运算符。这必须是一个成员函数,例如:

class MyClass {
  operator int() const
  { return your_number; }
  // other fields
};
您也可以实现 operator bool。然而,我强烈反对定义到整数类型(包括 bool)的转换运算符,因为这会使您的类可用于算术表达式中,从而很快变得混乱。
作为替代方案,例如,IOStreams 定义了到 void* 的转换。您可以像测试布尔值一样测试 void*,但是没有语言定义的从 void* 的隐式转换。另一种选择是定义具有所需语义的 operator!。
简而言之:定义到整数类型(包括布尔)的转换运算符是一个真的很糟糕的主意。

你说将类型转换为整数类型是一个坏主意..但这恰恰是你的代码片段所做的。同意operator bool()有意想不到的后果,也有更好的解决方案。但是将其转换为void*也并非完美:Foo x; delete x;现在会编译。bool operator!()更好,但你仍然需要执行if (!!x)来测试正面情况。如另一条评论中建议的那样,安全布尔习惯用法是最佳解决方案。 - Gareth Stockwell
3
1)根据定义转换运算符的语法,很明显 OP 并不了解,否则他应该能够编写最简单的解决方案。所以他学到了新东西。 2)我警告过他这是个坏主意。 3)安全 bool 更好,但似乎有点过度设计。如果将转换为 void* 应用于标准库,那对于我也是适用的。 - zvrba
9
在 C++11 中有 explicit operator bool()(在@plats的回答和@UncleBens的评论中提到),实现了 OP 所需的功能。如果在被接受的答案中包含这些信息,我认为会很好。 - fhahn

10

只需为您的类实现operator bool()即可。

例如:

class Foo
{
public:
    Foo(int x) : m_x(x) { }
    operator bool() const { return (0 != m_x); }
private:
    int m_x;
}

Foo a(1);
if (a) { // evaluates true
    // ...
}

Foo b(-1);
if (b) { // evaluates true
    // ...
}

Foo c(0);
if (c) { // evaluates false
    // ...
}

3
-1,在不明显的方式下会容易出现故障。查找“安全布尔惯用法(Safe Bool Idiom)”。 - greyfade
5
C++0x引入了explicit operator bool()以避免隐式破坏的情况? - UncleBens
@grayfade:同意 - 这个解决方案并不理想,使用 Safe Bool 习惯用法是更为健壮的方法。 - Gareth Stockwell

5

正如其他人所说,使用operator int()operator bool()是个不好的主意,因为它允许进行转换。使用指针是更好的选择。目前为止,最好的解决方案是返回一个成员(函数)指针:

class MyClass {
  void some_function () {}

  typedef void (MyClass:: * safe_bool_type) ();
  operator safe_bool_type () const
  { return cond ? &MyClass::some_function : 0; }
};

-2

C++会检查语句的结果是否等于零。因此,我认为您可以为您的类定义相等运算符,并定义在哪些条件下您的类与零不同。


不完全是这样... 这个值被转换为布尔值。只是通常将0转换为false,将其他任何值转换为true。重要的区别在于,如果你定义了 bool operator==( type const&, int );bool operator==( int, type const & );,你可以将对象与 0 进行比较,但不能将该对象用作条件。 - David Rodríguez - dribeas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接