class A {};
int main() {
A() = A();
return 0;
}
Por que este código compila? Não deveria haver algum erro que no lado esquerdo do operador de atribuição deve ser colocado lvalue? É A () lvalue? versão g ++ 4.7
Para os tipos internos, você estaria correto: o operador de atribuição interno requer um lvalue modificável no lado esquerdo.
No entanto, isso não está usando o operador integrado, mas a sobrecarga que é declarada implicitamente pela classe. Esta é uma função de membro, equivalente a
A().operator=(A());
e as funções de membro podem ser chamadas em rvalues .
operator=
não queiraoperator()
), mas não tem muito a ver com a pergunta. O exemplo não faz nada com o resultado da atribuição.A()
não chamaoperator()
, ele constrói um objeto do tipoA
.Se você realmente quiser, pode fazer com que ele não seja compilado com 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; }
( exemplo ao vivo )
Observe o
&
e&&
(também conhecido como qualificadores ref) no final das declarações dos váriosoperator=
formulários. Isso faz com que essas declarações sejam selecionadas para lvalues e rvalues respectivamente. No entanto, a versão rvalue, quando selecionada pela resolução de sobrecarga, faz com que o programa fique malformado porque foi excluído.O operador padrão gerado =, entretanto, não possui nenhum qualificador ref, o que significa que pode ser chamado para lvalues e rvalues; é por isso que o código da pergunta é compilado, embora
A()
seja um rvalue.fonte
O compilador C ++ fornece a todas as classes um construtor padrão, é o que acontece, com relação ao seu código, quando você diz A () = A (); ele apenas invoca o construtor com um objeto sem nome e a função retorna a referência ao objeto construído (implícito). É isso aí...
fonte