76 votes

Sémantique "auto" C ++11

Lorsque j'utilise C ++ 11 auto , quelles sont les règles de déduction de type en ce qui concerne le fait qu'il résolvera en une valeur ou en une référence?

Par exemple, parfois, il est clair:

 auto i = v.begin(); // Copy, begin() returns an iterator by value
 

Ceux-ci sont moins clairs:

 const std::shared_ptr<Foo>& get_foo();
auto p = get_foo(); // Copy or reference?

static std::shared_ptr<Foo> s_foo;
auto sp = s_foo; // Copy or reference?

std::vector<std::shared_ptr<Foo>> c;
for (auto foo: c) { // Copy for every loop iteration?
 

89voto

BЈовић Points 28674

La règle est simple: c'est comment vous le déclarez.

 int i = 5;
auto a1 = i;    // value
auto & a2 = i;  // reference
 

L'exemple suivant le prouve:

 #include <typeinfo>
#include <iostream>    

template< typename T >
struct A
{
    static void foo(){ std::cout<< "value" << std::endl; }
};
template< typename T >
struct A< T&>
{
    static void foo(){ std::cout<< "reference" << std::endl; }
};

float& bar()
{
    static float t=5.5;
    return t;
}

int main()
{
    int i = 5;
    int &r = i;

    auto a1 = i;
    auto a2 = r;
    auto a3 = bar();

    A<decltype(i)>::foo();
    A<decltype(r)>::foo();
    A<decltype(a1)>::foo();
    A<decltype(a2)>::foo();
    A<decltype(bar())>::foo();
    A<decltype(a3)>::foo();
}
 

Le résultat:

 value
reference
value
value
reference
value
 

14voto

Xeo Points 69818

§7.1.6.4 [dcl.spec.auto] p6

Une fois le type d'une demande de déclaration-id a été déterminée selon 8.3, le type de la variable déclarée à l'aide de la déclaration de-id est déterminée à partir du type de son initialiseur en utilisant les règles pour le modèle argument de la déduction.

Cela ne signifie rien autre chose que ce que auto modèles argument de modèle déduction au cours d'un appel de fonction.

template<class T>
void f(T){} // #1, will also be by-value

template<class T>
void g(T&){} // #2, will always be by-reference

Notez que #1 sera toujours copier l'argument passé, peu importe si vous passer une référence ou quoi que ce soit d'autre. (Sauf si vous spécifiez l'argument de modèle comme f<int&>(intref);.)

10voto

qqqqq Points 103

Tout ce que vous obtenez du côté droit (de "=") n'est jamais une référence. Plus spécifiquement, le résultat d'une expression n'est jamais une référence. Dans cette optique, notez la différence entre les résultats dans l'exemple.

 #include <typeinfo>
#include <iostream>
template< typename T >
struct A
{
    static void foo(){ std::cout<< "value" << std::endl; }
};
template< typename T >
struct A< T&>
{
    static void foo(){ std::cout<< "reference" << std::endl; }
};

float& bar()
{
    static float t=5.5;
    return t;
}

int main()
{
   auto a3 = bar();

   A<decltype(bar())>::foo();//notice the result 
    A<decltype(a3)>::foo();//notice the result
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X