Reusable safe_bool Implementation
Reusable safe_bool implementation
safe_bool
- what & why[^]?
In my understanding their implementation is broken (if fixable), but in the course I came up with my own that appears slightly more elegant to me:
template <typename T>
class safe_bool
{
protected:
typedef void (safe_bool::*bool_type)() const;
bool_type to_bool_type(bool b) const
{ return b ? &safe_bool<T>::safe_bool_true : 0; }
private:
void safe_bool_true() const {}
bool operator ==(safe_bool<T> const & rhs);
bool operator !=(safe_bool<T> const & rhs);
};
Can be used like this:
struct A : public safe_bool<A>
{
operator bool_type() const { return to_bool_type(true); }
// replaces:
// operator bool() const { return true; }
};
From all samples I found that's the cleanest to write and read, while only the two symbols bool_type
and to_bool_type
"escape" to derived classes.
I am putting this up for review, since I'm clearly at the limits of my understanding of the standard. However, the following test cases pass on VC 2008:
struct A : public safe_bool<A>
{
operator bool_type() const { return to_bool_type(true); }
};
struct B : protected safe_bool<B> // protected is ok, too
{
operator bool_type() const { return to_bool_type(false); }
};
struct C : public B
{
operator bool_type() const { return to_bool_type(rand() < RAND_MAX / 2); }
};
void SafeBootCompileFails()
{
A a, a2;
B b;
C c;
if (a) {} // Yes!
if (!a) {} // Yes!
a=a; // Yes! (default assignment op should be allowed)
a=a2; // Yes! (default assignment op should be allowed)
long l = a; // No!
if (a==a2) {} // No!
if (a!=a2) {} // No!
if (a<a2) {} // No!
if (a==b) {} // No!
if (a!=b) {} // No!
if (a<b) {} // No!
if (b==c) {} // No!
if (b!=c) {} // No!
if (b<c) {} // No!
a=b; // No!
b = c; // Yes, slicing. Not my problem today.
}