Boost logo

Boost :

From: Sam Partington (Sam.Partington_at_[hidden])
Date: 2003-03-11 06:22:19


Thanks for your comments Daniel, I will update the docs with a better
rationale and post the patch soon.

As for the issue below, I also have no idea how to go about automatically
selecting either method. Plus I think this might introduce complexities
which make the compiler's job that much harder to optimise. Could well be
wrong on that though.

Essentially I think the options are to

- document its unusual behaviour in the presence of other conversion
operators
- use the private operator int method.

So if we take the plusses and minuses for each method:

safe-bool:
+ obvious error messages (see list of error messages at end)
- problems with classes that provide other user-defined conversions
operators.
- requires declaration of operator! by user, which is a bit backward.

private operator int :
+ user provides operator bool, and our helper protects it from misuse, and
provides operator!
+ no clashes with other user-defined converion operators
- fails to work with if(a && func()) on MSVC 6 at least - 'operator && is
ambiguous'
- less helpful diagnostic messages.

The if (a && something) is quite a serious defect, but it compiles fine on
gcc 2.95.3.

So it comes down to two things,

1) How important is it to have legible diagnostics?
2) How important is it to behave properly with other user-defined
conversions?

My gut feeling is that I'd rather have the safe-bool method, but I suspect
my judgement is coloured by two things:
- I never use user defined conversion operators
- I use MSVC 6 as my main compiler, and not being able to do if (a && !a)
would bother me.

San

Diagonostic samples:
----------------------

template<class T, class B = ::boost::detail::empty_base> struct
other_bool_testable : B
{
public:
        operator bool() const { return !!static_cast<const T&>(*this); }
private:
        typedef signed char private_number_type;
        operator private_number_type() const;
};

#if defined(USE_OTHER_BOOL_TESTABLE)
        class A : public other_bool_testable<A>
#else
        class A : public bool_testable<A>
#endif
{
public:
        bool operator!() const { return false; }
};

void f(int);
void g(signed char);

void test(const A& a)
{
        if (a && !a)
        {
                f(a);
                g(a);
         }
}

MSVC 6
*******

safe-bool:
 test.cpp(321) : error C2664: 'f' : cannot convert parameter 1 from 'const
class A' to 'int'
        No user-defined-conversion operator available that can perform this
conversion, or the operator cannot be called

private operator :
test.cpp(319) : error C2593: 'operator &&' is ambiguous

// when the conversion is not an exact match to the private operator i.e.
int to signed char
test.cpp(347) : error C2664: 'f' : cannot convert parameter 1 from 'const
class A' to 'int'
        Ambiguous user-defined-conversion

//when it is an exact match
test.cpp(322) : error C2248: 'operator`signed char'' : cannot access private
member declared in class 'other_bool_testable<class A,class
boost::detail::empty_base>'
        C:\Work\SS\debugger\CodeScape\CBuilder.cpp(323) : see declaration of
'operator`signed char''

gcc 2.95.3 :
*********

safe-bool:

test.cpp: In function `void test(const A &)':
test.cpp:32: `const class A' used where a `int' was expected

with the private operator some_number() :

// if the private operator is not an exact match (e.g signed char to an int)
test.cpp:32: conversion from `const A' to `int' is ambiguous
test.cpp:6: candidates are:
other_bool_testable<A,boost::detail::empty_base>::operator bool() const
test.cpp:9:
other_bool_testable<A,boost::detail::empty_base>::operator signed char()
const

// if the private operator is an exact match you get
test.cpp:32: conversion from `const A' to `signed char' is ambiguous
test.cpp:6: candidates are:
other_bool_testable<A,boost::detail::empty_base>::operator bool() const
test.cpp:9:
other_bool_testable<A,boost::detail::empty_base>::operator signed char()
const
test.cpp:9: `other_bool_testable<A,boost::detail::empty_base>::operator
signed char() const' is private
test.cpp:35: within this context


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