class A {};
int main() {
A() = A();
return 0;
}
Pourquoi ce code est-il compilé ? Ne devrait-il pas y avoir une erreur indiquant qu'à gauche de l'opérateur d'affectation devrait être placée la valeur l ? A() est-il lvalue ? g++ 4.7 version
class A {};
int main() {
A() = A();
return 0;
}
Pourquoi ce code est-il compilé ? Ne devrait-il pas y avoir une erreur indiquant qu'à gauche de l'opérateur d'affectation devrait être placée la valeur l ? A() est-il lvalue ? g++ 4.7 version
Pour les types intégrés, vous avez raison : l'opérateur d'affectation intégré nécessite un élément modifiable, le valeur sur le côté gauche.
Cependant, il ne s'agit pas d'utiliser l'opérateur intégré, mais la surcharge déclarée implicitement par la classe. Il s'agit d'une fonction membre, équivalente à
A().operator=(A());
et les fonctions membres peuvent être appelées sur rvalues .
Si vous le souhaitez vraiment, vous pouvez faire en sorte qu'il ne compile pas 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 concret )
Notez que les &
y &&
(alias qualificateurs de ref) à la fin des déclarations des différents operator=
formes. Ces déclarations sont donc sélectionnées respectivement pour les valeurs l et les valeurs r. Cependant, la version rvalue, lorsqu'elle est sélectionnée par la résolution de surcharge, rend le programme mal formé parce qu'elle est supprimée.
L'opérateur= généré par défaut, cependant, n'a pas de qualificatif ref, ce qui signifie qu'il peut être appelé à la fois pour les valeurs l et les valeurs r. C'est pourquoi le code de la question se compile, même si A()
est une valeur r.
Le compilateur C++ fournit à toutes les classes un constructeur par défaut, c'est ce qui se passe, en ce qui concerne votre code, lorsque vous dites A()=A() ; il invoque simplement le constructeur avec un objet sans nom et la fonction renvoie une référence à l'objet construit (implicite). C'est tout...
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.