c++ convert class to boolean

17,089

Solution 1

You can define a user-defined conversion operator. This must be a member function, e.g.:

class MyClass {
  operator int() const
  { return your_number; }
  // other fields
};

You can also implement operator bool. However, I would STRONGLY suggest against doing it because your class will become usable in arithmetic expressions which can quickly lead to a mess. IOStreams define, for example, conversion to void*. You can test void* in the same way you can test a bool, but there are no language-defined implicit conversions from void*. Another alternative is to define operator! with the desired semantics.

In short: defining conversion operator sto integer types (including booleans) is a REALLY bad idea.

Solution 2

The C++11 approach is:

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
  }

Note the explicit keyword which prevents the compiler from converting implicitly.

Solution 3

Simply implement operator bool() for your class.

e.g.

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
    // ...
}

Solution 4

As others have stated, using operator int () or operator bool () is bad idea because of the conversions it allows. Using a pointer is better idea. The best know solution to this problem so far is to return a member (function) pointer:

class MyClass {
  void some_function () {}

  typedef void (MyClass:: * safe_bool_type) ();
  operator safe_bool_type () const
  { return cond ? &MyClass::some_function : 0; }
};
Share:
17,089
wyatt
Author by

wyatt

Updated on June 08, 2022

Comments

  • wyatt
    wyatt about 2 years

    With all of the fundamental types of C++, one can simply query:

    if(varname)
    

    and the type is converted to a boolean for evaluation. Is there any way to replicate this functionality in a user-defined class? One of my classes is identified by an integer, although it has a number of other members, and I'd like to be able to check if the integer is set to NULL in such a manner.

    Thanks.

  • greyfade
    greyfade almost 14 years
    -1, this breaks easily in unobvious ways. Look up the "Safe Bool Idiom."
  • UncleBens
    UncleBens almost 14 years
    C++0x has explicit operator bool() to avoid implicit breakage of the kind?
  • Gareth Stockwell
    Gareth Stockwell almost 14 years
    You state that conversion to integer types is a bad idea .. but then this is exactly what your code snippet does. Agreed that operator bool() has unintended consequences and there are better solutions. But conversion to void* is not perfect either: Foo x; delete x; will now compile. bool operator!() is better, but you still need to do if (!!x) to test for the positive case. As suggested in another comment, the Safe Bool idiom is the best solution.
  • Gareth Stockwell
    Gareth Stockwell almost 14 years
    @grayfade: agreed - this solution is not ideal and the Safe Bool idiom is a more robust approach.
  • David Rodríguez - dribeas
    David Rodríguez - dribeas almost 14 years
    Not really... the value is converted to a boolean. It is just that in general the conversion is done from 0 to false and from anything else to true. The important difference is that if you define bool operator==( type const&, int ); and bool operator==( int, type const & ); you can compare your object to 0 but you cannot use the object as a condition.
  • zvrba
    zvrba almost 14 years
    1) The OP clearly did not know the syntax for defining conversion operators, otherwise he would have been able to code the most trivial solution. So he learned something new. 2) I warned him about this being a bad idea. 3) Safe bool is better, but seems like an overengineering. If conversion to void* is good for the standard library, it's good for me too.
  • fhahn
    fhahn almost 8 years
    In C++11 there is explicit operator bool() (mentioned in @plats answer and @UncleBens comment) achieving what the OP wants. I think it would be good if this information would be included in the accepted answer.