Search code examples
c++c++11operator-keywordc++03explicit-conversion

isSet() or operator void*() or explicit opertor bool() or something else?


What is the state of the art about functions to check whether a value is set or not?

For example, the below iterator parses cells. Some cells contain a value, other cells are empty.

What is the most convenient way?

struct iterator 
{                                  //usage:
  bool isset() const               // if (it.isset()) 
  bool isSet() const               // if (it.isSet()) 
  bool empty() const               // if (it.empty()) 

  bool is_set()   const            // if (it.is_set()) 
  bool is_valid() const            // if (it.is_valid()) 

  operator void*() const;          // if (it) 

  explicit operator bool() const;  // if ((bool)it) or if(it) //thanks @stijn
  operator          bool() const;  // if (it) //why not implicit conversion?

  bool operator!() const;          // if (!!it)

  //throwing exception as pointed out by @MatthieuM
  Type get() { if (isSet()) return value_; else throw; }
  //usage:
  //     try {                    // if (it.isSet()) {
  //        Type x = it.get();    //    Type x = it.get();
  //     }                        // }
  //     catch (...) {            // else {
  //        //empty               //    //empty
  //     }                        // }

  //please feel free to propose something different
  ...
};

Reflections:

  1. my boss does not understand isset() => renamed to isSet()
  2. empty() is more about container collection, not just one single cell :(
  3. operator void* seems to be the logical way but deprecated in C++11 streams
  4. explicit operator is not yet supported (my code have to be compliant with old compilers)

I am reading:


Solution

  • I'm impressed that explicit_cast<T> from Imperfect C++: Practical Solutions [...] hasn't been mentioned. The concept is very simple - you set up a pseudo-keyword that actually is a templated class implementing the conversion that you want. I've been using this in my own C++ backports library without any important issue.

    class MyClass {
      ...implementation
      operator explicit_cast<bool> () const { 
          (return a bool somehow)
      }
    };
    

    You use the pseudo-keyword just as you would expect it to work:

    MyClass value;
    ...
    if ( explicit_cast<bool>(myobject) )  {
      do something
    } else {
      do something else
    }
    ...
    

    The best part of all, this solution can be mapped perfectly to native explicit operator in C++11, resulting in essentially zero overhead and native syntax. As a result, it's also more generic than trying to figure out if to call "isset", "is_set", "is_Set", "isSet", etc...