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?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top