Sie können den Konstruktor A1(char* name)
nicht mit einem String-Literal aufrufen, da ein String-Literal nicht in char*
konvertiert werden kann (eine solche veraltete Konvertierung existierte vor C++ 11). Oder, ein Programm, das den Konstruktor aufruft, ist schlecht ausgebildet, und die Implementierung darf die Kompilierung ablehnen.
Daher sucht die Überladungsauflösung nach anderen Alternativen. Die einzige andere mögliche Alternative, die die gleiche Anzahl von Argumenten hat, ist der Kopierkonstruktor.
Aus irgendeinem Grund scheint clang die implizite Konvertierung von Zeichenfolgenliteral zu A1
vorzuziehen, wodurch ein temporäres Objekt erstellt 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 gebildet, 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, wenn wir die Umwandlung nicht zulassen, dann stellt das Programm auch in dem aktuellen Standard-Modus:
class A1
{
public:
explicit A1(char* name){} // note the explicit
virtual ~A1() {}
private:
A1(const A1&) {}
};
G ++ verhält sich anders und Ihr Programm kompiliert fein (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 einfach zu lösen, während derselbe Fehler indirekt einen Fehler verursachte, der beim Lösen des Fehlers nicht hilfreich war.
@Andrew Ich denke, die Frage ist, warum ist der Kopierkonstruktor überhaupt erforderlich. – juanchopanza
Es gibt keine Zeile '31' in Ihrem Code. Bitte poste ein [MCVE] (http://stackoverflow.com/help/mcve) –
'A1 (" ")' ist ein Fehler, weil 'A1' keinen Konstruktor hat, der ein Zeichenfolgenliteral akzeptiert; Der Fehler, den Sie veröffentlichen, ist wahrscheinlich eine Kaskade von diesem Fehler (und sollte daher ignoriert werden, da er verschwindet, sobald Sie den ursprünglichen Fehler behoben haben) –