2012-08-02 12 views
13

¿La biblioteca de impulso proporciona una implementación de una expresión idiomática segura, para poder derivar mi clase de ella?idioma booleano seguro en impulso?

En caso afirmativo, ¿dónde está?

Si no, ¿cuáles son mis alternativas más allá de implementarlo yo mismo?


encontré la siguiente pregunta similar: "Is there a safe bool idiom helper in boost?" y la respuesta aceptada sugiere el uso de bool_testable<> en Boost.Operators.

Desafortunadamente, cuando revisé el boost manual no pude encontrarlo allí. El código que lo usa no compila también.

También tropecé con otra pregunta SO "Was boost::bool_testable<> relocated or removed?" y el comentario sugiere que el bool_testable en realidad nunca se realizó a ninguna versión de lanzamiento del impulso.

También hay un interesante article by Bjorn Karlsson sobre el tema que contiene un código que podría copiarse en mi proyecto. Sin embargo, espero que haya una biblioteca de utilidad comúnmente aceptada y mantenida (por ejemplo, impulso) que implemente eso ya.


Por razones de compatibilidad, no deseo confiar en C++ 11.

+3

¿Ha considerado resolver el problema al no convertir implícitamente a 'bool'? –

+2

Hay una implementación de Safe Bool reutilizable en la página 3 de este artículo: http://www.artima.com/cppsource/safebool.html –

+0

Gracias. No lo mencioné, pero sí lo vi y podría copiar y pegar ese código, pero esperaba que alguna biblioteca de utilidad comúnmente aceptada y mantenida (lo primero que se piensa es que el impulso se convierta en realidad) ya lo haga. – CygnusX1

Respuesta

15

No conozco una biblioteca de utilidad comúnmente aceptada que proporcione la expresión de salvo-bool. Ha habido algunos intentos dentro de Boost, y a menudo resultan en debates sobre cómo proporcionar una implementación de seguridad (nombrar convenciones, macros, inclusiones en línea, herencia). Como resultado, hay al menos tres implementaciones existentes dentro de Boost, con solo una de las implementaciones, Boost.Spirit.Classic's safe_bool, diseñada para uso externo.


detalles y conceptos para cada aplicación:

  • Boost.Range's safe_bool
    • Contenido dentro del directorio de detalle, por lo que no está diseñado expresamente para uso externo.
    • Implementado mediante el uso de un tipo de plantilla auxiliar y funciones miembro estáticas. Se espera
    • clase
    • La habilitado segura-bool a:
      • proporcionar una función miembro operator boost::range_detail::safe_bool<MemberPtr>::unspecified_bool_type() const que los delegados a la función estática safe_bool::to_unspecified_bool().
  • Boost.SmartPtr's operator_bool:
    • contenida dentro del directorio de detalle, por lo que no están diseñados expresamente para uso externo.
    • El archivo de cabecera está destinado a ser incluido directamente dentro de una definición de clase. Ver shared_ptr.hpp para un ejemplo.
    • Requiere incluir boost/detail/workaround.hpp antes de incluir smart_ptr/detail/operator.hpp.
    • Se espera que la clase habilitado segura-bool que rodea a:
      • proporcionar un tipo this_type.
      • Proporcione un tipo T.
      • Proporcione una variable de miembro T* px.
  • Boost.Spirit.Classic's safe_bool
    • Diseñado para uso externo.
    • Utiliza el patrón CRTP.
    • Diseñado para admitir el encadenamiento de clase base, lo que permite utilizar boost::spirit::class::safe_bool sin exigir herencia múltiple en la clase derivada. Se espera
    • clase
    • La habilitado segura-bool a:
      • derivan públicamente de boost::spirit::classic::safe_bool<Derived>. Si Derived ya hereda de Base, entonces use boost::spirit::classic::safe_bool< Derived, Base >.
      • Proporcione una función de miembro bool operator_bool() const.

Este ejemplo utiliza Boost 1,50. Cada clase debe evaluar como verdadero en contexto booleano si el entero pasado al constructor es mayor que 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; 
} 

salida resultante:

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

No sé de ninguna alternativa. Cuando me encontré con expresiones idiomáticas de lenguaje seguro, la mayoría de las implementaciones han sido variantes de copiar y pegar de la implementación proporcionada en Bjorn Karlsson's article.

Cuestiones relacionadas