在boost中的安全布尔惯用法?

13

Boost库是否提供了安全布尔习惯用法的实现,以便我可以从中派生我的类?

如果是 - 它在哪里?

如果不是 - 除了自己实现之外,我的选择是什么?


我发现了以下类似的问题:“在Boost中是否有安全的bool idiom helper?”,并且被接受的答案建议在Boost.Operators中使用bool_testable<>
不幸的是,当我查看boost manual时,我没有找到它。使用它的代码也无法编译。
我还偶然发现了另一个SO问题“boost::bool_testable<>是否已经被移动或删除?”,那里的评论表明bool_testable实际上从未发布到任何版本的boost中。

此外,Bjorn Karlsson撰写的文章也非常有趣,其中包含了一段可以复制粘贴到我的项目中的代码。然而,我希望有一个通常被接受并维护的实用程序库(例如boost),已经实现了这个功能。


出于兼容性考虑,我不想依赖于C++11。


3
你是否考虑过通过不隐式转换为bool来解决这个问题? - Mark B
2
这篇文章的第3页有一个可重用的安全布尔实现:http://www.artima.com/cppsource/safebool.html - Emile Cormier
谢谢。我没有提到,但我确实看到了那个,我可能会复制粘贴那段代码,但我希望一些常见且维护良好的实用程序库(首选是boost)已经做到了这一点。 - CygnusX1
1
你可能会对“http://stackoverflow.com/questions/10490675/was-boostbool-testable-relocated-or-removed”更新感兴趣。 - Daniel Frey
2个回答

15
我不知道有哪些常用的实用程序库提供了安全布尔值习惯用法。Boost 中已经尝试过几次,并且它们通常会引发关于如何提供安全布尔值实现的争议(命名约定、宏、内联包含、继承)。因此,至少在 Boost 中存在着三种实现方式,其中只有一种实现——Boost.Spirit.Classic 的安全布尔值——是为外部使用而设计的。
每种实现的详细信息和概念:
  • Boost.Range的safe_bool
    • detail目录中,因此不是专门为外部使用而设计的。
    • 通过使用模板助手类型和静态成员函数实现。
    • 预期启用safe-bool的类应:
      • 提供一个operator boost::range_detail::safe_bool< MemberPtr >::unspecified_bool_type() const成员函数,将委派给静态的safe_bool::to_unspecified_bool()函数。
  • Boost.SmartPtr的operator_bool
    • detail目录中,因此不是专门为外部使用而设计的。
    • 该头文件旨在直接包含在类定义内。请参阅shared_ptr.hpp进行了解示例。
    • 在包含smart_ptr/detail/operator.hpp之前,需要先包含boost/detail/workaround.hpp
    • 预期的安全布尔值启用类应:
      • 提供一个this_type类型。
      • 提供一个T类型。
      • 提供一个T* px成员变量。
  • Boost.Spirit.Classic的safe_bool
    • 专门为外部使用而设计。
    • 使用CRTP模式。
    • 旨在支持基类链接,允许在派生类上使用boost::spirit::class::safe_bool,而不强制执行多重继承。
    • 预期启用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;
}

输出结果:

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

我不知道任何其他的替代方法。当我遇到安全布尔型习惯用法时,大多数实现都是复制并粘贴 Bjorn Karlsson 在 这篇文章中提供的实现变体。


1
自从Boost 1.55版本以来,Boost.Core中有一个名为<boost/core/explicit_operator_bool.hpp>的头文件。它要求您定义bool operator!()并使用BOOST_EXPLICIT_OPERATOR_BOOL()宏(还有它的变体BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL())。

文档中有一个例子:

template< typename T >
class my_ptr
{
    T* m_p;

public:
    BOOST_EXPLICIT_OPERATOR_BOOL()

    bool operator!() const
    {
        return !m_p;
    }
};

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接