Pregunta

Hace poco he estado haciendo un gran refactorización donde yo estaba cambiando mucho de mi código para booleanos de retorno en lugar de un código de retorno explícito. Para ayudar en este refactorización decidí que apoyarse en lo posible por conseguir que me diga los lugares donde mi código necesario que se cambie el compilador. Hice esto mediante la introducción de la siguiente clase ( ver aquí por la verdad sobre cómo funciona este ) :

///
/// Typesafe boolean class
///
class TypesafeBool
{
private:
    bool m_bValue;
    struct Bool_ { 
        int m_nValue; 
    };
    typedef int Bool_::* bool_;
    inline bool_ True() const { return &Bool_::m_nValue; }
    inline bool_ False() const { return 0; }

public:
    TypesafeBool( const bool bValue ) : m_bValue( bValue ){}
    operator bool_() const { return m_bValue ? True() : False(); }
};

Ahora, en lugar de utilizar un tipo bool normal, como el tipo de retorno, que utiliza esta clase lo que significaba que no pude compilación algo como esto más:

TypesafeBool SomeFunction();
long result = SomeFunction(); // error

Gran: se ha hecho la refactorización manejable en una enorme base de código al permitir que el compilador de hacer un montón de trabajo duro para mí. Así que ahora que he terminado mi refactorización y me gusta bastante a mantener esta clase dando vueltas y seguir adelante usarlo ya que nos ofrece un nivel adicional de seguridad que el tipo incorporado bool no.

No obstante es uno "problema" que me está impidiendo hacer esto. En el momento en que hacemos un uso intensivo de la en nuestro código, y el problema es que no es compatible con esta nueva clase sin conversiones explícitas:

TypesafeBool result = ( 1 == 2 ? SomeFunction() : false ); // error: different types used
TypesafeBool result = ( 1 == 2 ? SomeFunction() : (TypesafeBool)false );

Si pudiera "resolver" este problema por lo que podía usar mi clase de una manera transparente que probablemente continuar usándolo durante todo el código base. ¿Alguien sabe de una solución a este problema? O es simplemente imposible de hacer lo que quiero?

Otros consejos

En el contexto del operador condicional, el tipo de la expresión es el tipo común de los últimos dos operandos. Las reglas completas para determinar este tipo común son un poco complejo, pero su caso pasa a ser trivial: si uno de los dos valores de retorno posibles es un tipo de clase, el otro valor debe tener la misma clase y el tipo común es, obviamente, también que clase.

Esto significa que si uno de los operandos es un TypesafeBool, entonces el otro debe ser así.

Ahora el problema que realmente estamos tratando de resolver ha sido resuelto antes. El truco no está proporcionando una clase; en lugar de utilizar un typedef. Véase, por ejemplo segura bool .

No sé acerca de una forma perfecta, el operador ternario tiene algunas restricciones en su uso ...

Sin embargo, ¿por qué no se definen dos constantes?

TypesafeBool const True = TypesafeBool(true);
TypesafeBool const False = TypesafeBool(false);

Y a continuación:

TypesafeBool result = ( 1 == 2 ? SomeFunction() : False );

Por supuesto, es un poco ortodoxo poco desde que juego en la capitalización de evitar la reutilización de una palabra reservada:)

¿Es una posibilidad para que el constructor de TypesafeBool explícito? Por supuesto, ahora el uso tiene que ser

TypesafeBool result( 1 == 2 ? b : false );

¿Podría utilizar un operador de asignación que se lleva en un bool como el argumento externo, así como uno que toma un TypesafeBool? Puede ser algo que probar ...

Buen intento, pero si su base de código es grande, es probable que mejor usar un corrector estática tales como PC-Lint para buscar bool implícita <->. Conversiones int en lugar

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top