Boost logo

Boost :

From: Ed Brey (brey_at_[hidden])
Date: 2003-09-05 13:43:25

Following is a bit of utility code that formalizes the safe implicit boolean conversion idiom. The idea behind the idiom is that a class should be implicitly convertible to bool, but not to integer or pointer types that can accidentally be misused.

The code defines the inert_bool type, which works just like a bool, except it isn't implicitly convertible to or from an arithmetic or pointer type.

struct inert_bool_structure {};
typedef inert_bool_structure const* inert_bool;
inline inert_bool make_inert_bool(bool b) {return reinterpret_cast<inert_bool>(b);}

A library class would use implicit_bool like this:

class my_class {
    operator boost::inert_bool() const {
        return boost::make_inert_bool(truth_state_);
    bool truth_state_;

This allows the library user to write code like this:

my_class my_object;
if (my_object) {...}

These are the motivations for implicit_bool:

1. It factors code that is otherwise repeated from class to class to implement the idiom.

2. It provides a consistent means of specifying the implicit conversion in source code, making the idiom more easily recognizable.

3. It avoids inefficiencies that other approaches impose. For instance, when I examine the optimized code generated by VC 7.1 from the technique used by shared_ptr et al, I find code that does a run-time fetch of the "unspecified" member address from a non-immediate variable. Another way to put it is that for shared_ptr, these two fragments generate different code:

if (ptr.get()) ...
if (ptr) ... // Less efficient.

This is why I didn't use a pointer to member, and why I used the reinterpret_cast. A pointer to non-member should be fine, AFAICT, since the only implicit operation is subtraction with another pointer of the same type, which is OK, since it has the same semantics as subtraction of two bools anyway.

What are people's thoughts of adding this to the utility library?

Ed Brey

Boost list run by bdawes at, gregod at, cpdaniel at, john at