为了支持没有explicit
关键字的编译器(例如 MSVC 2012),我必须实现安全的 bool 习惯用法。应该可以检查 bool 的类正在建模指向许多类的指针,因此它应该可以转换为这些指针。下面的代码说明了这个想法:
// 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;
}
如果我们使用explicit operator bool()
-based 实现一切正常。问题实际上在于基于“安全布尔”的实现中的模棱两可的可转换性。应该如何解决?
注意:考虑 bool 转换实现独立于其他指针转换实现。如果不可能,请告诉我如何在相关情况下实现它,例如,如果Convertible
其他转换运算符之一返回非空值,则计算结果为真。
UPD:我相信有一种方法可以使一个隐式转换比其他所有转换都更可取。