Frage

Ich habe vor kurzem einen großen Refactoring getan, wo ich eine Menge meiner Code Rückkehr booleans anstelle eines expliziten Return-Code zu ändern war. dieses Refactoring zu unterstützen ich auf dem Compiler, wo möglich, indem man es mir zu sagen, die Orte, wo mein Code benötigt geändert werden lehnen entschieden. Ich tat dies, indem Sie die folgende Klasse Einführung ( sehen hier für die Tatsachen auf, wie das funktioniert ) :

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

Nun, statt einen normalen bool Typen als Rückgabetyp verwendet, benutzen ich diese Klasse was bedeutete, dass ich konnte nicht Kompilierung so etwas wie diese mehr:

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

Große: es hat die Refactoring überschaubar auf einem riesigen Codebasis hergestellt, indem man die Compiler für mich eine Menge harter Arbeit tun. So jetzt habe ich mein Refactoring fertig und ich würde ganz wie diese Klasse zu halten, hänge herum und weiter verwendet es, da es uns ein zusätzliches Maß an Sicherheit bietet, dass die eingebauten in bool Typ nicht.

Es gibt jedoch ein „Problem“, das mich daran hindert, dies zu tun. Im Moment machen wir die starke Nutzung des ternären Operator in unserem Code, und das Problem ist, dass es ist nicht kompatibel mit dieser neuen Klasse ohne expliziten Casts:

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

Wenn ich könnte „lösen“ dieses Problem, so dass ich meine Klasse auf nahtlose Weise verwenden könnte ich wahrscheinlich über die Verwendung es in der gesamten Codebasis führen würde. Kennt jemand eine Lösung für dieses Problem? Oder ist es einfach unmöglich, zu tun, was ich will?

War es hilfreich?

Lösung

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

aber Vorsicht, in C ++ wird es als wirklich gefährlich, eine Klasse zu haben, der Bool gegossen werden kann. Sie sind gewarnt: -)

Sie können diese dort lesen, SAFEBOOL

Sie sollten explizit TypesafeBool nennen :: True () in allen Ihren ternären Tests.

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

Andere Tipps

Im Rahmen des bedingten Operators, die Art des Ausdrucks ist die allgemeinste Art von den letzten zwei Operanden. Die vollständigen Regeln diesen gemeinsamen Typen zu bestimmen sind ein wenig komplex, aber Ihr Fall geschieht trivial zu sein: wenn eine der beiden möglichen Rückgabewerte ist ein Klassentyp, muss der andere Wert hat die gleiche Klasse und die allgemeinste Art ist offensichtlich auch, dass Klasse.

Das bedeutet, dass, wenn einer der Operanden ein TypesafeBool ist, dann die anderes auch sein muss.

Jetzt das Problem, das Sie wirklich zu lösen versucht wurde, bevor gelöst. Der Trick ist, bietet nicht eine Klasse; stattdessen ein typedef verwenden. Siehe zum Beispiel sicher Bool .

Ich weiß nicht, um eine nahtlose Art und Weise, der ternäre Operator einige Einschränkungen auf seiner Verwendung hat ...

Doch warum nicht Sie definieren zwei Konstanten?

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

Und dann:

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

Natürlich ist es ein bisschen unorthodox, da ich auf der Kapitalisierung spiele ein reserviertes Wort zu vermeiden, die Wiederverwendung:)

Ist es eine Möglichkeit der Konstruktor von TypesafeBool explizit zu machen? Natürlich, jetzt die Nutzung sein muss,

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

Könnten Sie einen Zuweisungsoperator verwenden, die in einem bool als externes Argument nimmt, sowie eine, die eine TypesafeBool nimmt? Es könnte etwas auszuprobieren ...

sein

Netter Versuch, aber wenn Ihre Code-Basis groß ist, sind Sie wahrscheinlich besser dran mit einem statischen checker wie PC-Lint mit impliziten Bool aussehen <-> int. Konvertierungen statt

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top