Ste*_*ini 40 c++ boolean safe-bool-idiom
我正在尝试设计一个应用安全bool习语的bool包装器结构.
解决这个问题的经典实现非常简单:骨架可能是这样的:
struct Bool final
{
Bool() = default;
Bool(bool value)
: _value{value}
{}
explicit operator bool() const {
return _value;
}
private:
bool _value{false};
};
Run Code Online (Sandbox Code Playgroud)
我试图改进的部分是如何Bool构建的.
例如,我想通过设计避免隐式缩小:
Bool b1(45); // yields warnings, but it compiles
Bool b2{3}; // not ok by standard
Run Code Online (Sandbox Code Playgroud)
我试图用模板伤害自己,但没有成功.
我怎么能让它工作?
Fra*_*eux 57
您可以通过显式删除所有其他构造函数来实现此目的.
struct Bool final
{
template<class T>
Bool(T) = delete;
Bool(bool value);
};
Run Code Online (Sandbox Code Playgroud)
yur*_*hek 24
添加并显式删除模板构造函数:
template <typename T>
Bool(T) = delete;
Run Code Online (Sandbox Code Playgroud)
它bool比其他构造函数更好地匹配除了实际之外的任何东西,因此将阻止隐式转换.
pil*_*kch 18
如果你只需要:
一个只有"true"或"false"的变量,并且不能隐式转换为int/char/pointer,那么我会看一下使用枚举类:
enum class Bool {
False,
True,
};
Run Code Online (Sandbox Code Playgroud)
Bar*_*rry 14
我正在尝试设计一个应用安全bool习语的bool包装器结构.
别.
安全bool成语仅在C++ 03及更早版本中有用 - 如果你通过做类似的事情来表达你的类型是"truthy"的话:
struct A {
operator bool() const;
};
Run Code Online (Sandbox Code Playgroud)
你会遇到各种各样的问题,比如:
A{} + 4; // ok?!
A{} < 0; // ok?!
A{} == B{}; // ok if B also has operator bool??!
Run Code Online (Sandbox Code Playgroud)
所以安全的bool成语是使用函数指针(当然,函数指针!)解决这个意外的隐式转换问题.
在C++ 11中,我们有更好的解决方案:
struct A {
explicit operator bool() const;
};
Run Code Online (Sandbox Code Playgroud)
这正是我们想要的.实际上,它实际上是为解决这个问题而设计的.虽然安全的bool成语是相当复杂的脚手架,但explicit operator bool使用起来非常简单,只做正确的事情.你不需要一个包装器 - 使用你的包装器比explicit operator bool直接写它更难.
此外,你的包装器对用户施加了(a)不可导出性,因为你做了Bool最终的和(b)一个额外的bool成员,你必须保持同步,所以它引入而不是解决问题.考虑一下您需要做多少工作:
template <class T>
struct my_unique_ptr : Bool { ... };
Run Code Online (Sandbox Code Playgroud)
VS
template <class T>
struct my_unique_ptr {
T* ptr;
explicit operator bool() const { return ptr; }
};
Run Code Online (Sandbox Code Playgroud)