Ist der Aufruf des Copy-Konstruktors bei der Copy-Initialisierung explizit oder implizit?

8
%Vor%

In dem obigen Code, wie ich es verstehe, obwohl der Code-Konstruktor in den meisten Fällen weggelassen wird, ist es immer noch semantisch erforderlich, dass er aufgerufen wird. Meine Frage ist, ist der Aufruf explizit oder implizit? Für eine lange Zeit habe ich die Schlussfolgerung, dass der Aufruf von AAA::AAA(int) implizit ist, aber der Aufruf an den Kopierkonstruktor nicht. Heute habe ich versehentlich g ++ bekommen, um den obigen Code zu kompilieren und es wurde ein Fehler gemeldet. (VC12 kompiliert OK.)

In Abschnitt 8.5 des Standards:

  

Wenn der Zieltyp ein (möglicherweise cv-qualifizierter) Klassentyp ist:

     
  • Wenn die Initialisierung eine direkte Initialisierung ist oder wenn es sich um eine Kopierinitialisierung handelt, bei der die cv-unqualifizierte Version der Quelle ist   type ist dieselbe Klasse wie oder eine abgeleitete Klasse der Klasse   Ziel, Konstrukteure werden berücksichtigt. Die anwendbaren Konstruktoren   werden aufgezählt (13.3.1.3), und der beste wird durch Überladung gewählt   Auflösung (13.3). Der so ausgewählte Konstruktor wird zum Initialisieren aufgerufen   das Objekt mit dem Initialisierungsausdruck oder der Ausdrucksliste als sein   Argumente). Wenn kein Konstruktor angewendet wird oder die Überladungsauflösung ist   mehrdeutig, die Initialisierung ist schlecht ausgebildet.

  •   
  • Andernfalls (d. h. für die verbleibenden Fälle von Kopierinitialisierung) benutzerdefinierte Konvertierungssequenzen, die von der Quelle konvertieren können   Geben Sie den Zieltyp ein oder (wenn eine Konvertierungsfunktion verwendet wird)   zu einer davon abgeleiteten Klasse werden wie in 13.3.1.4 beschrieben gezählt,   und das beste wird durch Überladungsauflösung gewählt (13.3). Wenn die   Konvertierung kann nicht durchgeführt werden oder ist mehrdeutig, die Initialisierung ist   schlecht geformt. Die ausgewählte Funktion wird mit dem Initialisierer aufgerufen   Ausdruck als Argument; Wenn die Funktion ein Konstruktor ist, der Aufruf   initialisiert ein temporäres der cv-unqualifizierten Version des   Zieltyp Das Temporäre ist ein Prvalue. Das Ergebnis des Anrufs   (das ist die temporäre für den Konstruktor Fall) wird dann verwendet    direct-initialize , nach den obigen Regeln, das Objekt, das ist   das Ziel der Kopierinitialisierung. In bestimmten Fällen   Die Implementierung erlaubt es, das damit verbundene Kopieren zu eliminieren   direkte Initialisierung durch direktes Konstruieren des Zwischenergebnisses   in das Objekt, das initialisiert wird; siehe 12.2, 12.8.

  •   

Das fett dargestellte direct-initialize in den obigen Anführungszeichen bedeutet, dass der Aufruf zum Kopieren des Konstruktors explizit ist, oder? Ist g ++ falsch oder meine Interpretation des Standards falsch?

    
goodbyeera 17.02.2014, 06:43
quelle

2 Antworten

3

Sieht wie dieser Fehler aus: g ++ kann im zweiten Schritt der Kopierinitialisierung keine expliziten Konstruktoren aufrufen

  

g ++ kann den folgenden Code nicht kompilieren

%Vor%      

Der zweite Schritt einer Kopierinitialisierung (siehe 8.5 / 16/6/2) ist a   Direkt-Initialisierung, wobei explizite Konstruktoren berücksichtigt werden sollen   als Kandidatenfunktionen.

    
user1508519 17.02.2014, 07:23
quelle
1

Sieht so aus, als würde der Kopierkonstruktor nie aufgerufen. Nur Konstruktor wird aufgerufen. Der folgende Code kann den Kopierkonstruktor

aufrufen %Vor%

Nicht sicher, warum G ++ es kompiliert.

    
Simal Haneef 17.02.2014 09:06
quelle

Tags und Links