Question

Quelqu'un peut-il me expliquer pourquoi il y a une différence entre ces deux déclarations?

class A{};

const A& a = A();         // correct 

A& b = A();               // wrong

Il dit initialisation invalide de référence non-const de type A& d'un A temporaire de type

Pourquoi est-ce const question ici?

Était-ce utile?

La solution

références non-const doivent être initialisées avec l valeurs. Si vous pouvez les initialiser avec temporaires, alors que ferait ce qui suit?

int& foo = 5;
foo = 6; // ?!

références const ont la particularité qu'ils prolongent la durée de vie de l'arbitre, et comme ils sont const, il n'y a aucune possibilité que vous allez essayer de modifier quelque chose qui ne siège pas en mémoire. Par exemple:

const int& foo = 5;
foo = 6; // not allowed, because foo is const.

Rappelez-vous que les références ont fait de se référer à quelque chose, non seulement les variables temporaires. Par exemple, ce qui suit est valide:

int foo = 5;
int& bar = foo;
bar = 6;
assert(foo == 6);

Autres conseils

La terminologie sur ce point est un peu déroutant; vous pouvez les recherches un peu plus loin. Voici la réponse courte si:

Vous assignez un objet temporaire (le résultat de l'appel constructeur de la classe) à une variable. Un objet temporaire est une valeur R. Vous ne pouvez pas attribuer une valeur R à une référence non const.

Vous êtes autorisé à attribuer une valeur R à une référence const, bien que la raison d'être de ce qui lui est assez obscure.

Dans le langage C ++ il est illégal d'attacher une référence non-const à un rvalue, alors qu'il est parfaitement OK pour attacher une référence const à un rvalue. Par exemple, cela est légal

const int& r = 5;

alors que ce n'est pas

int &r = 5; // ERROR

Un objet temporaire de type A retourné par l'expression A() est un rvalue, de sorte que la règle ci-dessus applique dans votre cas aussi.

Pour un temporaire / rvalue, vous ne pouvez avoir une référence const.

Vous pouvez avoir une référence non-const à un non temporaire / lvalue.

A a;
A& b = a;

Je crois que la raison pour laquelle est de renforcer le fait qu'un rvalue est temporaire car il y a peu de valeur pour pouvoir modifier quelque chose qui va disparaître momentanément.

Parce que la norme dit donc:

  

§8.5.3.5 ... Dans le cas contraire, la référence sera une référence lvalue à un type const non volatile ...

Cependant, si vous le voulez bien, vous pouvez l'obtenir:

#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

Mais il faut savoir que la cr constante supposée ne const plus, aussi, et que vous engagez un comportement non défini. (§ 1.9 (4))

Comme le suggère le code ci-dessus, il n'y a aucune raison technique pour la différence. Au contraire, les concepteurs ont eu des cauchemars sur ce que les utilisateurs feraient avec des références non-const à temporaires.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top