Diese Arbeit umwandeln:Warum kann nur implizit Compiler char * std :: string in einigen Fällen
struct WithString {
WithString(std::string){};
};
void takeString(std::string){}
//implicit conversions:
takeString("hello");
WithString("hello");
Aber dies nicht:
WithString makeWithString() { return "hello";}
// error: no viable conversion from returned value of type 'const char [6]'...
Wenn "Hallo" wird implizit umgewandelt std::string
in den ersten beiden Fällen, warum kann es nicht im letzten Fall sein? Beachten Sie, dass ich den -Konstruktor nicht als explicit
angegeben habe, also würde ich eine solche Konvertierung erwarten.
Ich kann das Verhalten erhalten, indem dies zu tun arbeiten:
struct WithString {
WithString(std::string){};
WithString(const char *){};
};
bin ich über diese Kuriosität nur neugierig. Wenn ich eine Schätzung postuliere, würde ich sagen, dass es in den ersten beiden Arbeitsfällen die Umwandlung zwischen const char *
bis std::string
ist, aber im Fehlerfall würde dies stattdessen eine Kette von 2 Umwandlungen erfordern, zuerst von const char *
bis std::string
, und dann von std::string
zu WithString
. Vielleicht ist das der Grund, aber ich bin mir nicht sicher.
Wenn MSVS 2015 dies erlaubt, ist es fehlerhaft. Ich bin neugierig, was C++ 11, C++ 14, C++ 17 Funktionen Sie denken, sollte dieses Programm erlauben? –
In der Tat ermöglicht MSVS 2015 C++ dies. Ich denke, die Frage ist, ob const char * zu std: string eine _standard conversion_ ist oder nicht. Wenn es ist, dann ist es richtig; wenn nicht (d.h. benutzerdefinierte Umwandlung), dann ist es nicht. Das Überfahren des "Hallo" in Visual Studio für alle Fälle ergibt std :: string :: basic_string (const char * _Ptr). – vdovydaitis3
Und, ja, ich finde die zusätzliche Notiz unter [Initialisierung kopieren] (http://en.cppreference.com/w/cpp/language/copy_initialization): die implizite Konvertierung in Copy-Initialisierung muss T direkt aus dem Initialisierer, z. Die direkte Initialisierung erwartet eine implizite Konvertierung vom Initialisierer in ein Argument des T-Konstruktors. Struktur S {S (Std :: String) {}}; // implizit konvertierbar von std :: string S s ("abc"); // OK: Konvertierung von const char [4] nach std :: string S s = "abc"; // Fehler: keine Konvertierung von const char [4] zu S S s = "abc" s; // OK: Konvertierung von std :: string in S – vdovydaitis3