Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2003-11-27 00:21:05


Gee, I never thought the "safe_bool alternative?" thread would get so big.
Based on one of my replies in that thread, what about having:

template < class T, typename Boolean, Boolean TrueValue >
struct boolean_conversion
{
    operator Boolean() const
    { return static_cast<T const &>(*this) != T() ? TrueValue : 0; }

    friend bool operator !( T const &t )
    { return !static_cast<bool>( t ); }
};

Where "Boolean" should be a pointer-to-member(-function) type, but must be
any non-composite built-in type.

Note that now the core routines are defined as:
1. (In)equality
2. Default construction
2a. The default state must have semantics that map to FALSE and be the
_sole_ state that does this

However, points [2] or [2a] may be unacceptable to some types, so this new
helper can't always be used.

(Why aren't I'm concerned about [1]? Well, if you don't use a helper like
this and define a Boolean conversion, you have to define operators == and !=
anyway [even to just disable them]! The only types that can be used for
automatic Boolean contexts are the built-in non-composite types [integrals,
floats, pointers (to data or code), pointers-to-member,
pointers-to-member-function]. All of these types also get operators == and
!=, because Boolean conversions implicitly call these operators to compare
with zero or NULL. The automatic one-step conversion between an
user-defined type and a built-in type allows Boolean conversion contexts,
but also allows two objects of (potentially different) user-defined types to
be compared if they share the same Boolean-context-conversion type. You
have to define your own operators == and != to disable them or to give a
more precise definition of equivalence [because any two states that don't
map to FALSE would be considered equal].)

Daryle


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk