简体   繁体   English

加强安全bool成语?

[英]Safe bool idiom in boost?

Does the boost library provide an implementation of a safe bool idiom, so that I could derive my class from it? boost库是否提供了安全bool习语的实现,以便我可以从中派生我的类?

If yes - where is it? 如果是的话 - 在哪里?

If no - what are my alternatives beyond implementing it myself? 如果不是 - 除了自己实施之外我有什么其他选择?


I found the following similar question: " Is there a safe bool idiom helper in boost? " and the accepted answer suggests using bool_testable<> in Boost.Operators . 我发现了以下类似的问题:“ 在boost中是否有安全的bool成语助手? ”并且接受的答案建议在Boost.Operators中使用bool_testable<>

Unfortunately, when I checked the boost manual I couldn't find it there. 不幸的是,当我检查加速手册时,我找不到它。 Code using it fails to compile too. 使用它的代码也无法编译。

I also stumbled on another SO question " Was boost::bool_testable<> relocated or removed? " and the comment there suggests that the bool_testable actually never made to any release version of the boost. 我还偶然发现了另一个SO问题“ boost :: bool_testable <>是否重新定位或删除了? ”并且那里的评论表明bool_testable实际上从未对升级的任何发布版本做过。

There is also an interesting article by Bjorn Karlsson on the subject which contains a code which could be copy-pasted into my project. Bjorn Karlsson还有一篇关于这个主题的有趣文章,其中包含一个可以复制粘贴到我的项目中的代码。 I am hoping however, that there is a commonly accepted and maintained utility library (eg boost) that implements that already. 但我希望,有一个普遍接受和维护的实用程序库(例如boost)已经实现了。


For compatibility reasons, I do not want to rely on C++11. 出于兼容性原因,我不想依赖C ++ 11。

I do not know of a commonly accepted utility library that provides the safe-bool idiom. 我不知道一个普遍接受的实用程序库提供安全bool习语。 There have been a few attempts within Boost, and they often result in debates about how to provide a safe-bool implementation (naming conventions, macros, inline includes, inheritance). 在Boost中有一些尝试,它们经常导致关于如何提供安全bool实现(命名约定,宏,内联包含,继承)的争论。 As a result, there are at least three implementations existing within Boost, with only one of the implementations, Boost.Spirit.Classic's safe_bool , designed for external use. 因此,Boost中至少存在三个实现,其中只有一个实现Boost.Spirit.Classic的safe_bool ,专为外部使用而设计。


Details and concepts for each implementation: 每个实现的细节和概念:

  • Boost.Range's safe_bool Boost.Range的safe_bool
    • Contained within the detail directory, so not explicitly designed for external use. 包含在详细信息目录中,因此未明确设计用于外部使用。
    • Implemented by using a template helper type and static member functions. 通过使用模板辅助类型和静态成员函数实现。
    • The safe-bool enabled class is expected to: 安全bool启用类预计:
      • Provide an operator boost::range_detail::safe_bool< MemberPtr >::unspecified_bool_type() const member function that delegates to the static safe_bool::to_unspecified_bool() function. 提供一个operator boost::range_detail::safe_bool< MemberPtr >::unspecified_bool_type() const成员函数,该函数委托给静态safe_bool::to_unspecified_bool()函数。
  • Boost.SmartPtr's operator_bool : Boost.SmartPtr的operator_bool
    • Contained within the detail directory, so not explicitly designed for external use. 包含在详细信息目录中,因此未明确设计用于外部使用。
    • The header file is intended to be included directly within a class definition. 头文件旨在直接包含在类定义中。 See shared_ptr.hpp for an example. 有关示例,请参阅shared_ptr.hpp
    • Requires including boost/detail/workaround.hpp before including smart_ptr/detail/operator.hpp . 在包括smart_ptr/detail/operator.hpp之前,需要包括boost/detail/workaround.hpp
    • The surrounding safe-bool enabled class is expected to: 周围的安全布尔启用类预计将:
      • Provide a this_type type. 提供this_type类型。
      • Provide a T type. 提供T型。
      • Provide a T* px member variable. 提供T* px成员变量。
  • Boost.Spirit.Classic's safe_bool Boost.Spirit.Classic的safe_bool
    • Designed for external use. 专为外部使用而设计。
    • Uses the CRTP pattern. 使用CRTP模式。
    • Designed to support base class chaining, allowing boost::spirit::class::safe_bool to be used without mandating multiple inheritance on the derived class. 旨在支持基类链接,允许使用boost::spirit::class::safe_bool而不强制派生类的多重继承。
    • The safe-bool enabled class is expected to: 安全bool启用类预计:
      • Publicly derive from boost::spirit::classic::safe_bool< Derived > . 公开派生自boost::spirit::classic::safe_bool< Derived > If Derived already inherits from Base , then use boost::spirit::classic::safe_bool< Derived, Base > . 如果Derived已经从Base继承,那么使用boost::spirit::classic::safe_bool< Derived, Base >
      • Provide a bool operator_bool() const member function. 提供bool operator_bool() const成员函数。

This example uses Boost 1.50. 此示例使用Boost 1.50。 Each class should evaluate to true in boolean context if the integer passed to the constructor is greater than 0: 如果传递给构造函数的整数大于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;
}

Resulting output: 结果输出:

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

I do not know of any alternatives. 我不知道有任何替代方案。 When I have ran across safe-bool idioms, most of the implementations have been a copy-and-paste variants of the implementation provided in Bjorn Karlsson's article . 当我遇到安全bool习语时,大多数实现都是Bjorn Karlsson的文章中提供的实现的复制和粘贴变体。

Since Boost 1.55 there is <boost/core/explicit_operator_bool.hpp> header in Boost.Core. 自Boost 1.55起,Boost.Core中有<boost/core/explicit_operator_bool.hpp>标头。 It requires from you to define bool operator!() and use BOOST_EXPLICIT_OPERATOR_BOOL() macro (there are also variants of it BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() and BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL() ). 它要求您定义bool operator!()并使用BOOST_EXPLICIT_OPERATOR_BOOL()宏(还有它的变体BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()BOOST_CONSTEXPR_EXPLICIT_OPERATOR_BOOL() )。

The documentation has an example: 文档有一个例子:

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

public:
    BOOST_EXPLICIT_OPERATOR_BOOL()

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM