Safe bool idiom in boost?

Does the boost library provide an implementation of the safe bool idiom so that I can extract my class from it?

If so, where is it?

If not, what are my alternatives besides its implementation?


I found the following similar question: “ Is there a safe helper idiom for bool in boost? ” And the accepted answer assumes using bool_testable<> in Boost.Operators .

Unfortunately, when I checked boost manual , I could not find it. The code using it is also not compiled.

I also stumbled upon another SO question “ Was boost :: bool_testable <> moved or deleted? ” And the comment there says that bool_testable was actually never made for any version of boost.

There is also an interesting article > Bjorn Karlsson articles on a topic that contains code that could be copied to my project. However, I hope that there is a generally accepted and supported utility library (for example, boost) that already implements this.


For compatibility reasons, I don't want to rely on C ++ 11.

+13
c ++ boost safe-bool-idiom
source share
2 answers

I do not know the generally accepted utility library that provides the safe-bool idiom. There have been several attempts at Boost, and they often lead to debate on how to provide a safe-bool implementation (naming conventions, macros, inline attachments, inheritance). As a result, there are at least three implementations in Boost, with only one of the implementations, Boost.Spirit.Classic safe_bool , intended for external use.


Details and concepts for each implementation:

  • Boost.range safe_bool
    • It is contained in the details catalog, so it is clearly not intended for external use.
    • Implemented using the helper template type and static member functions.
    • Safe-bool-enabled class is expected:
      • Provide a member function operator boost::range_detail::safe_bool< MemberPtr >::unspecified_bool_type() const , which delegates the static function safe_bool::to_unspecified_bool() .
  • Boost.SmartPtr operator_bool :
    • It is contained in the details catalog, so it is clearly not intended for external use.
    • The header file is intended to be included directly in the class definition. See shared_ptr.hpp for an example.
    • You need to enable boost/detail/workaround.hpp before you enable smart_ptr/detail/operator.hpp .
    • The surrounding class with safe-bool support is expected to be:
      • Specify the type this_type .
      • Specify type T
      • Provide the T* px member variable.
  • Boost.Spirit.Classic safe_bool
    • Designed for external use.
    • Uses a CRTP template.
    • Designed to support the base class chain, allowing you to use boost::spirit::class::safe_bool without specifying multiple inheritance in the derived class.
    • Safe-bool-enabled class is expected:
      • Publicly derived from boost::spirit::classic::safe_bool< Derived > . If Derived already inheriting from Base , use boost::spirit::classic::safe_bool< Derived, Base > .
      • Provide member function bool operator_bool() const .

This example uses Boost 1.50. Each class must evaluate to true in a boolean context if the integer passed to the constructor is greater than 0:

 // 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 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 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; } 

Result:

  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 any alternatives. When I came across the safe-bool idioms, most of the implementations were copy and paste options presented in the article by Bjorn Karlsson .

+15
source share

Starting with Boost 1.55, Boost.Core has a header <boost/core/explicit_operator_bool.hpp> /licit_operator_bool.hpp>. You are required to define a bool operator!() And use BOOST_EXPLICIT_OPERATOR_BOOL() (there are also variants of this BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() and 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; } }; 
0
source share

All Articles