我不知道提供安全布尔习语的普遍接受的实用程序库。在 Boost 中进行了一些尝试,它们经常导致关于如何提供安全布尔实现(命名约定、宏、内联包含、继承)的争论。因此,Boost 中至少存在三个实现,其中只有一个实现,Boost.Spirit.Classic 的 safe_bool,是为外部使用而设计的。
每个实现的细节和概念:
- Boost.Range 的 safe_bool
- 包含在详细目录中,因此未明确设计为供外部使用。
- 通过使用模板助手类型和静态成员函数来实现。
- 启用安全布尔的类预计将:
- 提供一个
operator boost::range_detail::safe_bool< MemberPtr >::unspecified_bool_type() const
委托给静态函数的成员safe_bool::to_unspecified_bool()
函数。
- Boost.SmartPtr 的 operator_bool:
- 包含在详细目录中,因此未明确设计为供外部使用。
- 头文件旨在直接包含在类定义中。有关示例,请参见shared_ptr.hpp 。
boost/detail/workaround.hpp
在 include之前需要 include smart_ptr/detail/operator.hpp
。
- 周围的安全布尔启用类预计将:
- 提供一个
this_type
类型。
- 提供一个
T
类型。
- 提供一个
T* px
成员变量。
- Boost.Spirit.Classic 的 safe_bool
- 专为外部使用而设计。
- 使用CRTP模式。
- 旨在支持基类链接,允许
boost::spirit::class::safe_bool
在不强制派生类的多重继承的情况下使用。
- 启用安全布尔的类预计将:
- 公开派生自
boost::spirit::classic::safe_bool< Derived >
. 如果Derived
已经继承自Base
,则使用boost::spirit::classic::safe_bool< Derived, Base >
.
- 提供
bool operator_bool() const
成员函数。
此示例使用 Boost 1.50。如果传递给构造函数的整数大于 0,则每个类都应在布尔上下文中计算为 true:
// Safe-bool idiom with Boost.Range.
#include <boost/range/detail/safe_bool.hpp>
class range_bool
{
public:
range_bool( int x ) : x_( x ) {}
private:
// None of these are required, but makes the implementation cleaner.
typedef boost::range_detail::safe_bool< int range_bool::* > safe_bool_t;
typedef safe_bool_t::unspecified_bool_type unspecified_bool_type;
int dummy;
public:
operator unspecified_bool_type() const
{
return safe_bool_t::to_unspecified_bool( x_ > 0, &range_bool::dummy );
}
private:
int x_;
};
// Safe-bool idiom with Boost.SmartPtr.
#include <boost/detail/workaround.hpp>
class smart_ptr_bool
{
public:
smart_ptr_bool( int x ) { px = ( x > 0 ) ? &dummy : 0 ; }
private:
typedef smart_ptr_bool this_type; // -.
typedef int T; // :- Required concepts when using
T* px; // -' smart_ptr's operator_bool.
private:
T dummy; // Simple helper.
public:
#include <boost/smart_ptr/detail/operator_bool.hpp>
};
// Safe-bool idiom with Boost.Spirit.
#include <boost/spirit/include/classic_safe_bool.hpp>
class spirit_bool: public boost::spirit::classic::safe_bool< spirit_bool >
{
public:
spirit_bool( int x ) : x_( x ) {}
public:
// bool operator_bool() is required by the spirit's safe_bool CRTP.
bool operator_bool() const { return x_ > 0; }
private:
int x_;
};
#include <iostream>
int main()
{
std::cout << "range_bool( -1 ): " << range_bool( -1 ) << std::endl
<< "range_bool( 1 ): " << range_bool( 1 ) << std::endl
<< "smart_ptr_bool( -1 ): " << smart_ptr_bool( -1 ) << std::endl
<< "smart_ptr_bool( 1 ): " << smart_ptr_bool( 1 ) << std::endl
<< "spirit_bool( -1 ): " << spirit_bool( -1 ) << std::endl
<< "spirit_bool( 1 ): " << spirit_bool( 1 ) << std::endl;
return 0;
}
结果输出:
范围布尔(-1):0
范围布尔(1):1
smart_ptr_bool(-1):0
smart_ptr_bool(1):1
精神布尔(-1):0
精神布尔(1):1
我不知道任何替代方案。当我遇到安全布尔成语时,大多数实现都是Bjorn Karlsson 的文章中提供的实现的复制粘贴变体。