加强安全bool成语?

Cyg*_*sX1 13 c++ boost safe-bool-idiom

boost库是否提供了安全bool习语的实现,以便我可以从中派生我的类?

如果是的话 - 在哪里?

如果不是 - 除了自己实施之外我有什么其他选择?


我发现了以下类似的问题:" 在提升中是否有安全的bool成语助手? "并且接受的答案建议bool_testable<>Boost.Operators中使用.

不幸的是,当我检查加速手册时,我找不到它.使用它的代码也无法编译.

我还偶然发现了另一个问题" boost :: bool_testable <>是否重新定位或删除了? "并且那里的评论表明bool_testable实际上从未对任何发布版本的提升做出过.

Bjorn Karlsson还有一篇关于这个主题的有趣文章,其中包含一个可以复制粘贴到我的项目中的代码.但我希望,有一个普遍接受和维护的实用程序库(例如boost)已经实现了.


出于兼容性原因,我不想依赖C++ 11.

Tan*_*ury 15

我不知道一个普遍接受的实用程序库提供安全bool习语.在Boost中有一些尝试,它们经常导致关于如何提供安全bool实现(命名约定,宏,内联包含,继承)的争论.因此,Boost中至少存在三个实现,其中只有一个实现Boost.Spirit.Classic的safe_bool,专为外部使用而设计.


每个实现的细节和概念:

  • Boost.Range的safe_bool
    • 包含在详细信息目录中,因此未明确设计用于外部使用.
    • 通过使用模板辅助类型和静态成员函数实现.
    • 安全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之前包括smart_ptr/detail/operator.hpp.
    • 周围的安全布尔启用类预计将:
      • 提供一种this_type类型.
      • 提供一种T类型.
      • 提供T* px成员变量.
  • Boost.Spirit.Classic的safe_bool
    • 专为外部使用而设计.
    • 使用CRTP模式.
    • 旨在支持基类链接,允许boost::spirit::class::safe_bool在不强制派生类的多重继承的情况下使用.
    • 安全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;
}
Run Code Online (Sandbox Code Playgroud)

结果输出:

range_bool( -1 ):     0
range_bool(  1 ):     1
smart_ptr_bool( -1 ): 0
smart_ptr_bool(  1 ): 1
spirit_bool( -1 ):    0
spirit_bool(  1 ):    1

我不知道有任何替代方案.当我遇到安全bool习语时,大多数实现都是Bjorn Karlsson的文章中提供的实现的复制和粘贴变体.