class A {};
int main() {
A() = A();
return 0;
}
Pourquoi ce code se compile-t-il? Ne devrait-il pas y avoir une erreur qui devrait être placée sur le côté gauche de l'opérateur d'affectation lvalue? Est-ce que A () lvalue? version g ++ 4.7
Pour les types intégrés, vous auriez raison: l'opérateur d'affectation intégré nécessite une lvalue modifiable sur le côté gauche.
Cependant, cela n'utilise pas l'opérateur intégré, mais la surcharge qui est implicitement déclarée par la classe. Ceci est une fonction membre, équivalente à
A().operator=(A());
et les fonctions membres peuvent être appelées sur rvalues .
operator=
ne le vouliez pasoperator()
), mais cela n'a pas grand-chose à voir avec la question. L'exemple ne fait rien avec le résultat de l'affectation.A()
n'appelle pasoperator()
, il construit un objet de typeA
.Si vous voulez vraiment, vous pouvez le faire ne pas compiler avec C ++ 11:
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; }
( exemple en direct )
Notez le
&
et&&
(aka ref-qualifiers) à la fin des déclarations des différentsoperator=
formulaires. Cela permet de sélectionner ces déclarations pour lvalues et rvalues respectivement. Cependant, la version rvalue, lorsqu'elle est sélectionnée par résolution de surcharge, entraîne une mauvaise formation du programme car il est supprimé.L'opérateur généré par défaut =, cependant, n'a pas de qualificatif de référence, ce qui signifie qu'il peut être appelé à la fois pour lvalues et rvalues; c'est pourquoi le code de la question se compile, même s'il
A()
s'agit d'une rvalue.la source
Le compilateur C ++ fournit à toutes les classes un constructeur par défaut, c'est ce qui se passe, par rapport à votre code, quand vous dites A () = A (); il appelle simplement le constructeur avec un objet sans nom et la fonction renvoie une référence à l'objet construit (implicite). C'est ça...
la source