Ich habe die folgende Klasse:
%Vor%Ich suchte nach dem Grund, warum es ein Fehler ist, ohne Glück.
Ist es richtig, mit einem String-Literal zu konstruieren? wenn nein, warum? Wenn ja, was ist falsch an meinem Code?
Ich benutze gcc 5.3 mit Code :: Blocks 16.1.
Zuerst ist "4"
nicht std::string
, es ist const char[2]
. Dann
CLS c("4");
ist direkte Initialisierung , die Konstruktoren von CLS
werden auf die Initialisierung von% untersucht Code%. c
wird hier aufgenommen, weil CLS::CLS(string)
implizit in const char[]
über benutzerdefinierte Konvertierung (d. h. std::string
) konvertiert werden kann.
std::string::string(const char*)
ist Kopierinitialisierung ,
(Betonung meiner)
- Wenn
CLS d = "5";
ein Klassentyp ist und die cv-unqualifizierte Version des TypsT
nichtother
oder abgeleitet vonT
ist oder wennT
kein Klassentyp ist, aber der Typ vonT
ist ein Klassentyp, benutzerdefinierte Konvertierungssequenzen, die vom Typother
inother
(oder in einen vonT
abgeleiteten Typ, wennT
konvertiert werden können) ist ein Klassentyp und eine Konvertierungsfunktion ist verfügbar) werden untersucht und die beste wird durch Überladungsauflösung ausgewählt.
Das bedeutet, dass benutzerdefinierte Konvertierungssequenzen benötigt werden, um T
in const char[2]
zu konvertieren. Sogar CLS
könnte in const char[]
konvertiert werden, und std::string
könnte in std::string
konvertiert werden, aber nur eine benutzerdefinierte Umwandlung ist in einem implizite Konvertierungssequenz . Deshalb wird es abgelehnt.
(Betonung meiner)
Implizite Konvertierungssequenz besteht aus folgendem in dieser Reihenfolge:
1) null oder eine Standardkonvertierungssequenz;
2) null oder eine benutzerdefinierte Umwandlung;
3) null oder eine Standard-Konvertierungssequenz.
BTW: Wenn Sie es so ändern, dass CLS
explizit als Initialisierungsausdruck verwendet wird, funktioniert es einwandfrei. z.B.
a
und c
werden mit direkter Initialisierung initialisiert. b
und d
andererseits verwenden Initialisierung kopieren .
Der Unterschied besteht darin, dass der Compiler bei der Initialisierung der Kopie nach einer (einzelnen) benutzerdefinierten Konvertierung von (im Falle von d
) char const *
(dies ist ein bisschen ungenau, siehe Ende der Antwort) nach CLS
sucht. wohingegen für die direkte Initialisierung alle Konstruktoren versucht werden, wobei CLS(std::string)
verwendet werden kann, da eine Konvertierung std::string(char const *)
verfügbar ist.
Detail:
"5"
ist ein (C) String-Literal. Der Typ ist char const [2]
. Zuerst wird eine benutzerdefinierte Konvertierung von diesem Typ in CLS
gesucht. Da keine gefunden wird, wird die Standardkonvertierung von Type[N]
nach Type *
(mit Type
= char const
und N
= 2
) angewendet, was zu char const *
führt. Dann versucht der Compiler eine benutzerdefinierte Konvertierung von dieser in CLS
zu finden. Da es keine findet und es keine Standardkonvertierungen gibt, die es ausprobieren könnte, schlägt die Kompilierung fehl.
Tags und Links string c++ constructor initialization string-literals