Name: noob 2008-07-12 20:39
Is std::cout << "test"; true?
iostream::operator<< returns an iostream&, yes. However, iostream defines a cast to void*1. So, this can be used in a conditional part of an if expression:while(cin >> x)
cout << x + 1;operator void* isn't a very safe construct. But operator bool isn't so great either: it still allows you to say cout == cin and get true back, or pass it to a function expecting a boolean parameter. It's best to do something like this (where T is the name of the class implementing this pattern):
typedef bool(T::* unspecified_bool_type)();
operator unspecified_bool_type() const {
return convert_to_bool() ? &T::convert_to_bool : unspecified_bool_type();
}
bool convert_to_bool() const {
return !!(rand()%2);
}
template<class Derived>
struct testable {
typedef bool(Derived::* unspecified_bool_type)();
operator unspecified_bool_type() const {
return static_cast<Derived*>(this)->convert_to_bool() ? &Derived::convert_to_bool : unspecified_bool_type();
}
protected:
//Not const, thus, causes an error.
void _error_cannot_compare_testables_defaultly() {}
/**
* \remarks Don't allow comparisons.
* Declared as a friend function - it will be found due to argument dependent lookup,
* similar to friend name injection.
* This function is obviously invalid, and can never compile, but the compiler won't
* try to instantiate it until someone actually tries to compare.
*/
template<class T>
friend bool operator == (const Derived& left, const T& right) {
left._error_cannot_compare_testables_defaultly(); return false;
}
template<class T>
friend bool operator != (const Derived& left, const T& right) {
left._error_cannot_compare_testables_defaultly(); return false;
}
};