2010-02-23 6 views
9

Quelqu'un peut-il m'expliquer pourquoi il existe une différence entre ces deux instructions?Initialisation de référence en C++

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 type temporaire de type A

Pourquoi const question ici?

Répondre

14

Les références non const doivent être initialisées avec des valeurs l. Si vous pouviez les initialiser avec des temporaires, que feraient les suivants?

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

const références 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 doivent faire référence à quelque chose, pas seulement aux variables temporaires. Par exemple, ce qui suit est valide:

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

Attendez, cela signifie que je peux utiliser 'const classA & ref = ReturnsClassAByValue();'? Je pensais que la température allait mourir sur la ligne suivante. – Lucas

+2

Oui, vous pouvez l'utiliser. Le temporaire durera aussi longtemps que la variable de référence: http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!378.entry –

+1

Génial, merci. Sur SO, vous apprenez quelque chose de nouveau chaque jour ... – Lucas

1

Pour une valeur/valeur temporaire, vous ne pouvez avoir qu'une référence const.

Vous pouvez avoir une référence non-const à une valeur 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.

+1

Accordée; Je pense que le PO cherche pourquoi c'est le cas. – fbrereto

1

En langage C++, il est illégal d'attacher une référence non-const à un rvalue, alors qu'il est parfaitement correct d'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 une rvalue, de sorte que la règle ci-dessus applique dans votre cas aussi.

+0

Une valeur rvalue est une valeur temporaire sans nom, comme la valeur de retour d'une fonction. – thebretness

+0

@thebretness: Pas nécessairement. Par exemple, une constante enum est une valeur, mais elle est * nommée *. – AnT

3

La terminologie sur ceci est un peu confuse; vous voudrez peut-être les chercher un peu plus loin. Voici la réponse courte:

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

Vous êtes autorisé à attribuer une valeur R à une référence const, bien que la logique de l'autoriser soit plutôt obscure.

0

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 sachez que la cr constante supposée ne const plus, aussi, et vous encourez un comportement non défini. (§1.9 (4))

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