2013/3/14 John Maddock
class Testable
{ bool ok_; typedef void (Testable::*bool_type)() const; void this_type_does_not_support_****comparisons() const {}
public: explicit Testable(bool b=true):ok_(b) {}
operator bool_type() const { return ok_==true ? &Testable::this_type_does_not_****support_comparisons : 0;
} };
Testable t(true);
bool b = t; // Compiles OK - Ooops!
I'm curious, why is this bad? I personally hate the fact, that the above doesn't compile for explicit operator bool(), which leads to idioms like !!t.
It's bad because the type isn't logically convertible to bool, BTW the !!t idiom isn't required in C++11 mode, the following works just fine:
#include <iostream>
class Testable { bool ok_; typedef void (Testable::*bool_type)() const; void this_type_does_not_support_**comparisons() const {} public: explicit Testable(bool b=true):ok_(b) {}
explicit operator bool() const { return ok_; } };
int main() { Testable t(true);
if(t) std::cout << "Yeh\n";
if(!t) std::cout << "Oh\n";
bool b = t ? true : false;
return 0;
}
bool do_something_with_a_Testable() { Testable t; [...] // return t; doesn't work return !!t; } So bool b = t; // I wish it worked with Testable::explicit operator bool, but doesn't. And the explicitness of operator bool should block situations, where bool is treated as an arithmetic type, like: t + 1 which compiles if Testable provides an implicit conversion to bool. John Maddock wrote:
It's not directly connected - except that what should have failed to compile - a function that looks like:
bool functor(number const& a, number const& b) { return a - b; }
However, I now see why allowing
bool b = t
can do harm, as in your example above.
2013/3/14 Peter Dimov
I see; yes, this is something that works with "safe bool" and has been explicitly disallowed for the new explicit operator bool.
Too bad, IMHO. Regards, Kris