Kann ein Cast-Operator explizit sein?

84

Wenn es um Konstruktoren geht, explicitverhindert das Hinzufügen des Schlüsselworts, dass ein begeisterter Compiler ein Objekt erstellt, wenn dies nicht die erste Absicht des Programmierers war. Gibt es einen solchen Mechanismus auch für Gießbetreiber?

struct Foo
{
    operator std::string() const;
};

Hier möchte ich zum Beispiel in der Lage sein, Fooin eine zu verwandeln std::string, aber ich möchte nicht, dass eine solche Besetzung implizit erfolgt.

qdii
quelle

Antworten:

101

Ja und nein.

Dies hängt davon ab, welche Version von C ++ Sie verwenden.

  • C ++ 98 und C ++ 03 werden nicht unterstützt explicit Typkonvertierungsoperatoren
  • Aber C ++ 11 tut es.

Beispiel,

struct A
{
    //implicit conversion to int
    operator int() { return 100; }

    //explicit conversion to std::string
    explicit operator std::string() { return "explicit"; } 
};

int main() 
{
   A a;
   int i = a;  //ok - implicit conversion 
   std::string s = a; //error - requires explicit conversion 
}

Kompilieren Sie es mit g++ -std=c++0x, Sie erhalten folgende Fehlermeldung:

prog.cpp: 13: 20: Fehler: Konvertierung von 'A' in nicht skalaren Typ 'std :: string' angefordert

Online-Demo: http://ideone.com/DJut1

Aber sobald Sie schreiben:

std::string s = static_cast<std::string>(a); //ok - explicit conversion 

Der Fehler verschwindet: http://ideone.com/LhuFd

Übrigens wird in C ++ 11 der explizite Konvertierungsoperator als "Kontextkonvertierungsoperator" bezeichnet, wenn er in einen Booleschen Wert konvertiert . Wenn Sie mehr über implizite und explizite Konvertierungen erfahren möchten, lesen Sie dieses Thema:

Hoffentlich hilft das.

Nawaz
quelle
9
Selbst in C ++ 03 ist es einfach, die implizite Konvertierung zu vermeiden. Rufen Sie einfach die Funktion auf toStringund nicht operator std::string. Dies kann natürlich bei einigen Vorlagen zu Problemen führen. Ich habe es immer benutzt toStringund es hat mir nie Probleme bereitet, aber ich stelle mir vor, dass dies von Ihrem Codierungsstil abhängen könnte.
James Kanze
@MatthieuM. Genau wie operator std::string():-).
James Kanze
2
Ich benutze to_stringstattdessen. Es hilft, dass es so ist, wie C ++ 11 es nennt, also hilft es, vorwärtskompatiblen Code zu schreiben und hilft bei Vorlagen.
Luis Machuca
1
std::string s(a)oder std::string s{a}sollte auch funktionieren als static_cast<std::string>(a).
alfC
2
@Bin: Weil das vom Compiler beim Schreiben kontextuellexplicit operator bool() aufgerufen wird . Beachten Sie, dass die hier stattfindende Konvertierung (informell) als kontextbezogene Konvertierung und nicht als implizite Konvertierung bezeichnet wird. if(std::cin)
Nawaz