|
Boost : |
From: Daniel Wallin (dalwan01_at_[hidden])
Date: 2003-11-28 08:59:51
Daniel James wrote:
> On Thu, 27 Nov 2003 16:33:10 -0500, David Abrahams wrote:
>
>
>>What am I missing?
>>
>>template <class T>
>>struct bool_testable
>>{
>> private:
>> struct impl { int x; };
>> typedef int impl::*safe_bool;
>> public:
>> operator safe_bool() const
>> {
>> return !*static_cast<T const*>(this) ? 0 : &impl::x;
>> }
>>};
>>
>>struct X : bool_testable<X>
>>{
>> bool operator!() const { return true; }
>>};
>
>
> If a user forgets to make their operator! const, then it can't be called,
> so the compiler uses a cast to safe_bool in order to apply ! to that (or
> at least it does in gcc). This causes infinite recursion. As this is a
> fairly easy mistake to make, I'd see it as a problem.
>
> It could be rewritten to explicitly call operator!(), but that would mean
> that operator!() would have to be a member function. But that might be too
> limiting?
>
> Personally, I like Joel de Guzman's version, but I also like using boost
> operators, so for me a mix of the two would be good:
>
> [snip]
Here's another one:
template <class T>
struct bool_testable
{
protected:
bool_testable()
{
BOOST_STATIC_ASSERT(!(
boost::is_convertible<T, int>::value)
);
}
struct bool_
{
bool_(bool x_) : x(x_) {}
bool x;
};
private:
typedef bool bool_::*safe_bool;
public:
operator safe_bool() const
{
return static_cast<T const&>(*this).operator bool_().x
? &bool_::x
: 0;
}
};
struct X : bool_testable<X>
{
operator bool_() const { return false; }
};
... And another one:
template <class T>
struct bool_testable
{
protected:
bool_testable()
{
BOOST_STATIC_ASSERT(!(
boost::is_convertible<T, int>::value)
);
}
private:
struct impl { bool x; };
typedef bool impl::*safe_bool;
struct need_to_implement_operator_not {};
public:
operator safe_bool() const
{
return !static_cast<T const&>(*this)
? 0
: &impl::x;
}
need_to_implement_operator_not operator!() const;
};
struct X : bool_testable<X>
{
bool operator!() const { return false; }
};
-- Daniel Wallin
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk