C ++ 11 auto: et si la référence est constante?

Veuillez regarder le code simple suivant:

class Foo { public: Foo(){} ~Foo(){} Foo(const Foo&){} Foo& operator=(const Foo&) { return *this; } }; static Foo g_temp; const Foo& GetFoo() { return g_temp; } 

J’ai essayé d’utiliser l’ auto comme ceci:

 auto my_foo = GetFoo(); 

Je m’attendais à ce que my_foo soit une référence constante à Foo , qui est le type de retour de la fonction. Cependant, le type d’ auto est Foo , pas la référence. De plus, my_foo est créé en copiant g_temp . Ce comportement n’est pas si évident pour moi.

Pour obtenir la référence à Foo , je devais écrire comme ceci:

 const auto& my_foo2 = GetFoo(); auto& my_foo3 = GetFoo(); 

Question : Pourquoi auto déduit le type de retour de GetFoo en tant qu’object, pas une référence?

Lire cet article: Apparition et disparition de consts en C ++


La déduction de type pour les variables automatiques en C ++ 0x est essentiellement la même que pour les parameters de modèle. (Autant que je sache, la seule différence entre les deux est que le type des variables automatiques peut être déduit des listes d’initialisation, alors que les types de parameters de modèle peuvent ne pas l’être). jamais const int):

 auto a1 = i; auto a2 = ci; auto a3 = *pci; auto a4 = pcs->i; 

Lors de la déduction de type pour les parameters de modèle et les variables automatiques, seules les consts de niveau supérieur sont supprimés. Étant donné un modèle de fonction prenant un pointeur ou un paramètre de référence, la constance de ce qui est pointé ou référencé est conservée:

 template void f(T& p); int i; const int ci = 0; const int *pci = &i; f(i); // as before, calls f, ie, T is int f(ci); // now calls f, ie, T is const int f(*pci); // also calls f, ie, T is const int 

Ce comportement est d’anciennes nouvelles, comme il le fait pour C ++ 98 et C ++ 03. Le comportement correspondant aux variables automatiques est bien sûr nouveau pour C ++ 0x:

 auto& a1 = i; // a1 is of type int& auto& a2 = ci; // a2 is of type const int& auto& a3 = *pci; // a3 is also of type const int& auto& a4 = pcs->i; // a4 is of type const int&, too 

Comme vous pouvez conserver le qualificatif cv si le type est une référence ou un pointeur, vous pouvez le faire:

 auto& my_foo2 = GetFoo(); 

Au lieu de devoir le spécifier comme const (même chose pour volatile ).

Edit: Quant à savoir pourquoi auto déduit le type de retour de GetFoo() comme une valeur au lieu d’une référence (qui était votre question principale, désolé), considérez ceci:

 const Foo my_foo = GetFoo(); 

Ce qui précède va créer une copie, car my_foo est une valeur. Si auto devait renvoyer une référence lvalue, ce qui précède ne serait pas possible.