2012-08-02 2 views
13

Поддерживает ли библиотека ускорения реализацию безопасной идиомы bool, чтобы я мог извлечь из нее свой класс?Безопасная идиома bool в boost?

Если да, то где это?

Если нет - каковы мои альтернативы, кроме его реализации?


Я нашел следующий подобный вопрос: «Is there a safe bool idiom helper in boost?» и принятый ответ предполагает использование bool_testable<> в Boost.Operators.

К сожалению, когда я проверил boost manual, я не смог его найти. Код, использующий его, также не может скомпилироваться.

Я также наткнулся на другой вопрос «Was boost::bool_testable<> relocated or removed?», и комментарий там говорит о том, что bool_testable на самом деле никогда не делал никакой версии релиза.

Существует также интересный article by Bjorn Karlsson по теме, который содержит код, который может быть скопирован в мой проект. Однако я надеюсь, что есть общепринятая и поддерживаемая библиотека утилиты (например, boost), которая уже реализует это.

По соображениям совместимости, я не хочу полагаться на C++ 11.

+3

Рассматривали ли вы решение проблемы, неявно преобразовывая ее в 'bool'? –

+2

На странице 3 этой статьи есть возможность повторного использования Safe Bool: http://www.artima.com/cppsource/safebool.html –

+0

Спасибо. Я не упоминал об этом, но я видел это, и я мог бы скопировать этот код, но я надеялся, что уже принятая и общепринятая и поддерживаемая утилитарная библиотека (в первую очередь, в первую очередь). – CygnusX1

ответ

15

Я не знаю общепринятой библиотеки утилиты, которая обеспечивает идиому safe-bool. В Boost было несколько попыток, и они часто приводят к дебатам о том, как обеспечить реализацию safe-bool (соглашения об именах, макросы, встроенные вложения, наследование). В результате в Boost существует не менее трех реализаций, только одна из реализаций, Boost.Spirit.Classic's safe_bool, предназначена для внешнего использования.


Детали и концепции для каждой реализации:

  • Boost.Range's safe_bool
    • Содержится в детали каталога , так явно не предназначен для наружного применения.
    • Реализовано с использованием вспомогательного типа шаблона и статических функций-членов.
    • Безопасная-BOOL включен класс ожидается:
      • Обеспечить функцию члена operator boost::range_detail::safe_bool<MemberPtr>::unspecified_bool_type() const, что делегаты статической safe_bool::to_unspecified_bool() функции.
  • Boost.SmartPtr's operator_bool:
    • Содержится в детали каталога , так явно не предназначен для наружного применения.
    • Файл заголовка предназначен для включения непосредственно в определение класса. См. Пример shared_ptr.hpp.
    • Требуется в том числе boost/detail/workaround.hpp до включения smart_ptr/detail/operator.hpp.
    • Окружающий безопасной BOOL включен класс ожидается:
      • Обеспечить this_type типа.
      • Укажите тип T.
      • Укажите переменную-член T* px.
  • Boost.Spirit.Classic's 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.

В этом примере используется Повышение 1.50. Каждый класс должен оценить, правда, в логическом контексте, если число передается конструктору больше, чем 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'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

Я не знаю ни одной альтернативы. Когда я столкнулся с идиомами safe-bool, большинство реализаций были вариантами копирования и вставки реализации, приведенными в Bjorn Karlsson's article.

 Смежные вопросы

  • Нет связанных вопросов^_^