Verwenden von Clang 3.7 auf Windows-Plattform
Siehe folgenden Code:
%Vor%Ich erhalte den folgenden Fehler:
%Vor%Der Kopierkonstruktor von A1 wird öffentlich gemacht, der Fehler wird beseitigt!
Was ist hier passiert?
Beachte: dass ich (wie ich sollte) ändere
%Vor%Ich bekomme keine Fehler und alles kompilieren wie erwartet
Sie können den Konstruktor A1(char* name)
nicht mit einem String-Literal aufrufen, da ein String-Literal nicht in char*
konvertierbar ist (eine solche veraltete Konvertierung existierte vor c ++ 11). Oder, ein Programm, das den Konstruktor aufruft, ist schlecht gebildet, und die Implementierung darf die Kompilierung ablehnen.
Daher sucht die Überladungsauflösung nach anderen Alternativen. Die einzige andere mögliche Alternative, die dieselbe Anzahl von Argumenten hat, ist der Kopierkonstruktor.
Aus irgendeinem Grund scheint clang die implizite Umwandlung von Zeichenfolgenliteral in A1
zu bevorzugen, wodurch ein temporäres Objekt erzeugt wird, das für die Kopierinitialisierung verwendet werden kann, anstatt die direkte Konstruktion aus dem Literal zu verwenden. Dieses Verhalten führt zu dem verwirrenden Kompilierungsfehler.
Beide Alternativen sind schlecht geformt, und Clang warnt davor: warning: ISO C++11 does not allow conversion from string literal to 'char *' [-Wwritable-strings]
. Das Programm kompiliert, wenn Sie den Standardmodus auf älter als C ++ 11 setzen (in diesem Fall wäre das Programm wohlgeformt, obwohl es eine veraltete Konvertierung verwendet). Interessanterweise kompiliert das Programm, wenn wir die Konvertierung nicht zulassen, selbst im aktuellen Standardmodus:
G ++ verhält sich anders und Ihr Programm kompiliert gut (mit der entsprechenden Warnung natürlich). Beide Compiler scheinen in dieser Hinsicht dem Standard zu entsprechen.
Moral der Geschichte: Lesen Sie immer auch die Warnungen. In diesem Fall war die Warnung vollkommen klar und leicht zu lösen, während derselbe Fehler indirekt einen Fehler verursachte, der beim Lösen des Fehlers nicht hilfreich war.
Ich stelle mir vor, dass dies nur ein Artefakt ist, wie die Diagnose generiert wird.
char*
akzeptiert, stimmt nicht überein, wie Sie wissen private
A1
von Ihrem ""
-Argument instanziieren kann, um dies zu ermöglichen private
constructors Ein könnte argumentieren, dass dies ein Qualitätsproblem ist.
Amüsant GCC 6.1.0 (sogar im pedantischen C ++ 14 Modus) kompiliert Ihren Code wie ursprünglich geschrieben > spuckt nur eine Warnung für die gebrochene wörtliche Umwandlung aus.
Tags und Links c++ clang c++11 copy-constructor