Domanda

Ho recentemente fatto un enorme refactoring in cui stavo cambiando molto del mio codice per booleani ritorno invece di un codice di ritorno esplicito. Per aiutare questo refactoring ho deciso di appoggiarsi al compilatore dove possibile ottenerlo per dirmi i luoghi dove il mio codice necessario per essere cambiato. Ho fatto questo con l'introduzione della seguente classe ( vedi qui per la verità su come funziona questo ) :

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

Ora, invece di utilizzare un tipo normale bool come tipo di ritorno, ho usato questa classe il che significa che ho potuto qualcosa che non compilazione del genere più:

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

Grande: ha fatto il refactoring gestibile su un enorme base di codice lasciando il compilatore fare un sacco di duro lavoro per me. Così ora ho finito il mio refactoring e mi piace molto per mantenere questa classe in giro e vai avanti usarlo dato che ci offre un ulteriore livello di sicurezza che il built-in di tipo bool non.

C'è comunque un "problema" che mi impedisce di fare questo. Al momento facciamo un uso pesante del ternario operatore nel nostro codice, e il problema è che esso non è compatibile con questa nuova classe senza cast espliciti:

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

Se potessi "risolvere" questo problema in modo che potessi usare la mia classe in condizioni di continuità avrei probabilmente continuare a utilizzarlo per tutta la base di codice. Qualcuno sa di una soluzione a questo problema? O è solo impossibile fare quello che voglio?

È stato utile?

Soluzione

      class CCastableToBool
      {  
      public:
         // ...
         operator bool() const
         {  
           //...
           {
              return true;
           } 
           //...
           return false;
         }  
      private:
         // ...
      }; 

ma attenzione, in C ++ è considerato davvero pericoloso avere una classe che può essere colato a bool. Siete avvertiti: -)

si può leggere questo c'è, SafeBool

Si dovrebbe chiamare esplicitamente TypesafeBool :: True () in tutti i test ternari.

TypesafeBool result = ( 1 == 2 ? SomeFunction().True() : false );

Altri suggerimenti

Nel contesto dell'operatore condizionale, il tipo dell'espressione è tipo comune degli ultimi due operandi. Il regolamento completo per determinare questo tipo comune sono un po 'complessa, ma tuo caso sembra essere banale: se uno dei due possibili valori restituiti è un tipo di classe, l'altro valore deve avere la stessa classe e il tipo corrente è ovviamente anche che classe.

Ciò significa che se uno degli operandi è un TypesafeBool, allora l'altro deve essere pure.

Ora il problema si sta veramente cercando di risolvere è stato risolto prima. Il trucco non sta fornendo una classe; invece utilizzare un typedef. Si veda ad esempio sicuro bool .

Non so di un modo senza soluzione di continuità, l'operatore ternario ha alcune restrizioni al suo uso ...

Tuttavia, il motivo per cui non si definisce due costanti?

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

E poi:

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

Certo, è un po 'poco ortodosso da quando gioco sulla capitalizzazione per evitare il riutilizzo di una parola riservata:)

E 'una possibilità per rendere il costruttore di TypesafeBool esplicito? Naturalmente, ora l'utilizzo deve essere

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

Potresti utilizzare un operatore di assegnazione che prende in un bool come argomento esterno, così come uno che prende una TypesafeBool? Potrebbe essere qualcosa di provare ...

Bel tentativo, ma se il vostro codice di base è di grandi dimensioni, si sono probabilmente meglio usare un correttore statica come PC-Lint per cercare bool implicita <->. Conversioni int invece

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top