class A {};
int main() {
A() = A();
return 0;
}
¿Por qué se compila este código? ¿No debería haber algún error que en el lado izquierdo del operador de asignación debería colocarse lvalue? ¿Es A () lvalor? versión g ++ 4.7
Para los tipos integrados, estaría en lo correcto: el operador de asignación integrado requiere un lvalue modificable en el lado izquierdo.
Sin embargo, esto no usa el operador integrado, sino la sobrecarga que la clase declara implícitamente. Esta es una función miembro, equivalente a
A().operator=(A());
y las funciones miembro se pueden llamar en rvalues .
operator=
no lo quieras deciroperator()
), pero no tiene mucho que ver con la pregunta. El ejemplo no hace nada con el resultado de la tarea.A()
no llamaoperator()
, construye un objeto de tipoA
.Si realmente lo desea, puede hacer que no se compile con 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; }
( ejemplo vivo )
Tenga en cuenta los
&
y&&
(también conocidos como calificadores de referencia) al final de las declaraciones de los distintosoperator=
formularios. Esto hace que esas declaraciones se seleccionen para lvalues y rvalues respectivamente. Sin embargo, la versión rvalue, cuando se selecciona por resolución de sobrecarga, hace que el programa tenga un formato incorrecto porque se elimina.El operador generado predeterminado =, sin embargo, no tiene ningún calificador de referencia, lo que significa que se puede llamar tanto para lvalues como para rvalues; es por eso que el código de la pregunta se compila, aunque
A()
es un rvalue.fuente
El compilador de C ++ proporciona a todas las clases un constructor predeterminado, eso es lo que sucede, con respecto a su código, cuando dice A () = A (); simplemente invoca al constructor con un objeto sin nombre y la función devuelve una referencia al objeto construido (implícito). Eso es...
fuente