3

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.

Antwort

5

I would say it is because in the first two working cases, the conversion is between const char * to std::string, but in the error case, this would instead require a chain of 2 conversion, first from const char * to std::string, and then from std::string to WithString. So perhaps that is the reason, but I'm not sure.

Genau.

Ohne Ihre const char* Konstruktor Überlastung dies:

WithString makeWithString() { return "hello";} 

würde zwei benutzerdefinierte implizite Konvertierungen erfordern; eins zu std::string und ein anderes zu WithString. Das ist nicht möglich.

Hier gibt es aber nur eine implizite Konvertierung (zu std::string):

takeString("hello"); 

Und das gleiche ist hier richtig, denn die nachfolgende "Umwandlung" zu WithString explizit:

WithString("hello"); 

I can get the behavior to work by doing this:

struct WithString { 
    WithString(std::string){}; 
    WithString(const char *){}; 
}; 

Ja, das sollten Sie tun.

-2

liest implicit conversions Abschnitt in dem C++ Standard. Ich habe den folgenden Code in VS 2015 versucht und es kompiliert ohne Fehler.

#include <string> 

struct WithString { 
    WithString(std::string) {}; 
}; 

void takeString(std::string) {} 

//implicit conversions: 
void someFunc() 
{ 
    takeString("hello"); 
    WithString("hello"); 
    WithString t = "hello"; 
} 

WithString makeWithString() { return "hello"; } 

Es scheint, dass VS2015 falsch ist (eine Umwandlung von const char * string als Standardkonvertierung Behandlung).Der folgende Code sollte nach dem Standard arbeiten, aber erzeugt einen Fehler in VS2015:

WithString makeWithString() { return "hello"s; } 
WithString t = "hello"s; 

Siehe auch copy initialization. In den Notes ruft es explizit WithString t = "hello"; einen Fehler auf.

+0

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? –

+0

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

+0

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

Verwandte Themen