Boost logo

Boost :

From: Daniel Frey (daniel.frey_at_[hidden])
Date: 2003-11-27 05:57:01

Daryle Walker wrote:
> //========================================================================
> template <class T, class B = ::boost::detail::empty_base>
> struct bool_testable : B
> {
> friend bool operator!(const T& t) { return !static_cast<bool>(t); }
> private:
> typedef signed char private_number_type;
> operator private_number_type() const;
> #endif
> };
> //========================================================================
> There's a slight difference; the sample I gave only deals with blocking the
> other integral-as-pusedo-Boolean conversions, you added an "operator !()"
> too. I guess your core routine, which the type's creator has to provide, is
> an "operator bool()".


> Why do you provide a block to just a "signed char"
> conversion?

We don't need more. All conversions are now either correct conversions
to bool, inaccessible conversions to signed char or ambiguous
conversions to all other integral types (because "T->bool" and
"T->signed char" are equally good conversions).

> If your
> response is to use an "operator X T::*()" as the core routine instead, then
> why have the "signed char" conversion at all?

That won't work. I think Dave tried it out ;)

>>>Wasn't there a problem with compilers trying
>>>to match a Boolean context to all of these operators, leading to
>>>inaccessibility and ambiguity, instead of using "bool" as an unique exact
>>I don't understand what exactly you refer to. Could you elaborate, please?
> I think the problem when I tried this years ago was when I tried to put my
> type in a Boolean context, that instead of the compiler using the "bool"
> converter because it's the only accessible conversion, it decided that all
> my converters were equally good and gave me an ambiguity error (and
> inaccessibility errors since some of the candidates were private). My
> compiler back then did not give the "bool" type a higher priority than the
> other built-in integral types.

I remember that one compiler had a problem, but still adding more
conversion operators doesn't help. The compiler is simply broken and
cannot work with the above boolean conversion protection idiom, because
it doesn't convert T to bool in this context: if(T()). It needs
if(!!T()), I think Sam Partington mentioned it in the docs for

> Some of my stuff (like modulo in the sandbox) does use Peter's method.

Which is good, as Peter's idiom is better if you don't mind applying it
by hand. I just don't see how we can offer it as a convenient and safe
base class. Actually, I don't mandate switching existing code to use the
operators library's bool_testable for two reasons:

a) It creates dependencies to the operators library which are IMHO not

b) Once again: Peter's safe bool idiom is better.

So the question is: Why should we add bool_testable at all? I think that
the operators library should offer it to make it easy for those that are
unaware (and probably ignorant) to the problem at all. Users add
operator bool(). The operators library allows them to add a single line
to protect it. They don't need to know the exact details. That's better
than doing nothing and it's easier to learn about Peter's idiom.
Hopefully they switch to Peter's idiom when they have time, but since
then, bool_testable should be helpful.

Regards, Daniel

Daniel Frey
aixigo AG - financial solutions & technology
Schloß-Rahe-Straße 15, 52072 Aachen, Germany
fon: +49 (0)241 936737-42, fax: +49 (0)241 936737-99
eMail: daniel.frey_at_[hidden], web:

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