试图找到一个“简单易用”的safe_bool习语/实现,我最终得到了自己的。
问:此实施是否正确?
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 {}
private:
bool operator ==(safe_bool<T> const & rhs);
bool operator !=(safe_bool<T> const & rhs);
};
这样使用:
struct A : public safe_bool<A>
{
// operator bool() const { return true; }
operator bool_type() const { return to_bool_type(true); }
};
现有基类的唯一补充是to_bool_type
,但我希望我的其他一切也正确。
我使用的测试用例(VC9)can be found here。
我在实现中看到的缺点:bool_type
和to_bool_type
在派生类中可见,这可能不会安抚每个人。此外,使用错误的模板参数(例如,在复制和粘贴期间引入的class B : public safe_bool<A>
)将被忽视。
答案 0 :(得分:4)
你提到的“错误的模板参数”问题几乎完全被@Terry Mahaffey引用的wikibooks.org解决方案中的static_cast
消除了(“没有虚函数的可测试性”)。我唯一能看到他们解决方案的错误就是单独的safe_bool_base
类,它会在多个基类(或compressed_pair
中的元素)中出现时抑制空基优化。就个人而言,我会将该实现移回模板中。
答案 1 :(得分:1)
使用指向成员函数的指针作为bool别名是惯用的,就像你在这里一样。
您的实施看起来是正确的,但稍微不完整。见http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool
IMO safe_bool属于弊大于利的事物类别;即这个成语引入的复杂性和混淆以及理解它所需的心理努力比它想要解决的初始问题更大。