Fehler: Die Basisklasse 'A1' hat einen privaten Kopierkonstruktor

8

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

    
Mr. G 23.06.2016, 10:04
quelle

2 Antworten

3

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:

%Vor%

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.

    
user2079303 23.06.2016, 10:21
quelle
6

Ich stelle mir vor, dass dies nur ein Artefakt ist, wie die Diagnose generiert wird.

  • Zuerst versucht die Suche, einen Konstruktor zu finden, der Ihrem "Aufruf" entspricht (es ist kein Aufruf, aber was auch immer)
  • Der ctor, der char* akzeptiert, stimmt nicht überein, wie Sie wissen
  • Der einzige andere Kandidat ist private
  • Der Compiler versucht zu sehen, ob er ein temporäres A1 von Ihrem "" -Argument instanziieren kann, um dies zu ermöglichen
  • Dabei kann wieder nur private constructors
  • gefunden werden
  • Der Compiler beschließt, sich darüber zu beschweren, bevor er etwas anderes tut

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.

    
quelle

Tags und Links