I have to implement safe bool idiom in order to support compilers that do not have explicit
keyword (MSVC 2012 for example). The class that should be checkable for bool is modelling a pointer to many classes and therefore it should be convertible to these pointers. The following code illustrates the idea:
// Uncomment this line to change implementation to 'safe bool'
// #define _COMPILER_NO_EXPLICIT
#if !defined(_COMPILER_NO_EXPLICIT)
#define OPERATOR_BOOL_MYTYPE(...)
#define OPERATOR_BOOL_IMPLEMENTATION(...) \
public: \
explicit operator bool() const noexcept \
{ \
return __VA_ARGS__; \
}
#else
#define OPERATOR_BOOL_MYTYPE(...) \
private: \
void safe_bool() {}; \
typedef __VA_ARGS__ safe_bool_my_type_t; \
typedef void (safe_bool_my_type_t::*safe_bool_t)()
#define OPERATOR_BOOL_IMPLEMENTATION(...) \
public: \
operator safe_bool_t() const noexcept \
{ \
return __VA_ARGS__ ? \
&safe_bool_my_type_t::safe_bool : \
nullptr; \
}
#endif
class Convertible
{
public:
operator int*() const
{ return nullptr; }
operator double*() const
{ return nullptr; }
OPERATOR_BOOL_MYTYPE(Convertible);
OPERATOR_BOOL_IMPLEMENTATION(false);
};
int main(void)
{
Convertible a;
if (a)
{
// this 'if' statement introduces compilation error
// in 'safe bool' implementation
}
return 0;
}
If we use explicit operator bool()
-based implementation everything works fine. The problem is actually in ambiguous convertibility in "safe bool" based implementation. How should it be solved?
Note: Consider bool conversion implementation to be independent from other to-pointer conversion implementations. If it is not possible give me a clue how to implement it in dependent case e.g. if Convertible
evaluates to true iff one of the other conversion operators are returning non null value.
UPD: I believe there is a way that makes one implicit conversion to be more preferable than all the other.