2013-04-30 18 views
84
class A {}; 

int main() { 
A() = A(); 
return 0; 
} 

Warum kompiliert dieser Code? Sollte da nicht ein Fehler sein, der auf der linken Seite des Zuweisungsoperators lvalue platziert werden sollte? Ist A() lvalue? g ++ Version 4.7A() = A() - warum kompiliert es?

Antwort

87

Für eingebaute Typen, würden Sie richtig sein: Zuweisungsoperator erfordert einen änderbar lvalue auf der linken Seite, die eingebaut.

Dies verwendet jedoch nicht den integrierten Operator, sondern die Überladung, die implizit von der Klasse deklariert wird. Dies ist eine Mitgliedsfunktion entspricht

A().operator=(A()); 

und Elementfunktionen können aufrvalues ​​aufgerufen werden.

+0

ist dies nicht mit A (A())? – stardust

+7

ist es nicht Kopierinitialisierung? – stardust

+0

@Named seinen Aufruf 'operator =' auf A –

32

Wenn Sie wirklich wollen, können Sie es nicht mit C++ 11 kompilieren machen:

class A { 
    template <typename T> 
    void operator=(T&&) && = delete; // no op= for rvalues 

    // generate other special members normally 
    A() = default; 
    A(A const&) = default; 
    A(A&&) = default; 
    ~A() = default; 
    // op= only for lvalues 
    A& operator=(A&&) & = default; 
    A& operator=(A const&) & = default; 
}; 

int main() { 
A() = A(); // error 
return 0; 
} 

(live example)

Notiere die am Ende & und && (aka ref-Qualifier) ​​von die Erklärungen der verschiedenen operator= Formulare. Dadurch werden diese Deklarationen für lvalues ​​bzw. rvalues ​​ausgewählt. Wenn die rvalue-Version jedoch durch Überladungsauflösung ausgewählt wird, wird das Programm schlecht dargestellt, da es gelöscht wird.

Der standardmäßig generierte Operator = hat jedoch kein ref-Qualifikationsmerkmal, dh er kann sowohl für lvalues ​​als auch für rvalues ​​aufgerufen werden; deshalb kompiliert der Code in der Frage, obwohl A() ein rvalue ist.

1

C++ - Compiler stellt allen Klassen einen Standardkonstruktor zur Verfügung, was in Bezug auf Ihren Code passiert, wenn Sie sagen: A() = A(); Es ruft nur den Konstruktor mit einem namenlosen Objekt auf und die Funktion gibt den Verweis auf das konstruierte Objekt zurück (implizit). Das ist es ...

Verwandte Themen