Boost logo

Boost :

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


On 11/24/03 5:16 AM, "Daniel Frey" <daniel.frey_at_[hidden]> wrote:

> Daryle Walker wrote:
>> Sorry if we discussed this before, but why wouldn't:
>>
>> struct no_integers_except_bool
>> {
>> private:
>> // None of these are defined
>> operator signed char() const;
>> operator unsigned char() const;
>> operator signed short() const;
>> operator unsigned short() const;
>> operator int() const;
>> operator unsigned() const;
>> operator signed long() const;
>> operator unsigned long() const;
>>
>> #ifdef BOOST_HAS_LONG_LONG
>> operator signed long long() const;
>> operator unsigned long long() const;
>> #endif
>>
>> operator char() const;
>> operator wchar_t() const;
>> };
>>
>> block the bad effects of having an "operator bool() const"? (Your class
>> would inherit from this one.)
>
> We already have this in the operators library, have a look at
> bool_testable (currently in CVS only, not in 1.30.2).

OK, I see it now. Here it is, so we can refer to it later in this message:

//========================================================================
template <class T, class B = ::boost::detail::empty_base>
struct bool_testable : B
{
    friend bool operator!(const T& t) { return !static_cast<bool>(t); }
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
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? What about the other built-in integral types ("bool" and
"signed char" are equally convertible to the other b-i.i.t's)? If your
response is to use an "operator X T::*()" as the core routine instead, then
why have the "signed char" conversion at all?

>> 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
>> match?
>
> 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 think it's also fair to mention that Peter's safe bool idiom (with
> returning a member variable pointer instead of a member function
> pointer) is superiour if you are not afraid of the more complex
> implementation. If you want a safe and easy-to-use base class,
> bool_testable is AFAIK the best you can get.

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

Daryle


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