Referência de inicialização em C++
-
22-09-2019 - |
Pergunta
Alguém pode me explicar que há uma diferença entre essas duas declarações?
class A{};
const A& a = A(); // correct
A& b = A(); // wrong
Ele diz
inválido de inicialização de referência não constante do tipo A&
a partir de uma temporário do tipo A
Por que const
importa aqui?
Solução
Não-const referências devem ser inicializadas com l-valores.Se você pode inicializar-los com temporários e, em seguida, qual seria o seguinte fazer?
int& foo = 5;
foo = 6; // ?!
const
referências tem a propriedade especial de que eles estendem a vida do árbitro, e uma vez que eles são const
, não há nenhuma possibilidade de que você irá tentar modificar algo que não fica na memória.Por exemplo:
const int& foo = 5;
foo = 6; // not allowed, because foo is const.
Lembre-se de que as referências, na verdade, referir-se a algo, não apenas variáveis temporárias.Por exemplo, o seguinte é válido:
int foo = 5;
int& bar = foo;
bar = 6;
assert(foo == 6);
Outras dicas
A terminologia sobre isso é um pouco confusa; Você pode pesquisá -los um pouco mais longe. Aqui está a resposta curta:
Você está atribuindo um objeto temporário (o resultado de chamar o construtor da classe) a uma variável. Um objeto temporário é um valor R. Você não pode atribuir um valor R a uma referência não consagrada.
Você pode atribuir um valor R a uma referência const, embora a justificativa para permitir que seja bastante obscura.
Na linguagem C ++, é ilegal anexar uma referência não-consistente a um RValue, enquanto é perfeitamente aceitável anexar uma referência constante a um RValue. Por exemplo, isso é legal
const int& r = 5;
Enquanto isso não é
int &r = 5; // ERROR
Um objeto temporário do tipo A
devolvido pela expressão A()
é um rvalue, portanto a regra acima se aplica no seu caso também.
Para um temporário/rvalue, você só pode ter uma referência const.
Você pode ter uma referência não consultiva a um não-temporário/LValue.
A a;
A& b = a;
Acredito que a razão é reforçar o fato de que um Rvalue é temporário, pois há pouco valor em poder modificar algo que desaparecerá momentaneamente.
Porque o padrão diz isso:
§8.5.3.5 ... Caso contrário, a referência deve ser uma referência lvalue a um tipo const não volátil ...
No entanto, se você quiser muito, pode obtê -lo:
#include <iostream>
int main()
{
const int & cr=5;
int & r=const_cast<int &>(cr);
r=6;
std::cout<<r;
}
// outputs 6 with c++/clang++, Debian 8, amd64
Mas lembre -se de que o suposto CR constante também não é mais constante e você incorre em comportamento indefinido. (§1.9 (4))
Conforme sugerido pelo código acima, não há razão técnica para a diferença. Em vez disso, os designers tinham pesadelos sobre o que os usuários fariam com referências não consultivas a temporários.