2011-08-21 15 views
59

favor, eche un vistazo a la siguiente código simple:C++ 11 auto: ¿y si obtiene una referencia constante?

class Foo 
{ 
public: 
    Foo(){} 
    ~Foo(){} 

    Foo(const Foo&){} 
    Foo& operator=(const Foo&) { return *this; } 
}; 

static Foo g_temp; 
const Foo& GetFoo() { return g_temp; } 

He intentado utilizar auto así:

auto my_foo = GetFoo(); 

que esperaba que my_foo habrá una referencia constante a Foo, que es el regreso tipo de la función. Sin embargo, el tipo de auto es Foo, no es la referencia. Además, se crea my_foo copiando g_temp. Este comportamiento no es tan obvio para mí.

Con el fin de obtener la referencia a Foo, que necesitaba escribir así:

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

Pregunta: ¿Por qué auto deducir el tipo de retorno de GetFoo como un objeto, no una referencia?

+0

¿Qué compilador estás usando? –

+0

compilador de VC++ 2010 e Intel C++ – minjang

Respuesta

49

leer este artículo: Appearing and Disappearing consts in C++


Tipo deducción por variables auto en C++ 0x es esencialmente el mismo que de los parámetros de plantilla. (Hasta donde yo sé, la única diferencia entre los dos es que el tipo de variables automáticas se puede deducir de las listas de inicializadores , mientras que los tipos de parámetros de plantilla pueden no serlo.) Cada una de las siguientes declaraciones declara variables de tipo int (nunca int const):

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

durante tipo deducción por los parámetros de plantilla y variables de automóviles, sólo consts de nivel superior se eliminan. Dada una plantilla de función que toma un parámetro puntero o referencia, el constness de lo que está señalado o referido se conserva:

template<typename T> 
void f(T& p); 

int i; 
const int ci = 0; 
const int *pci = &i; 

f(i);    // as before, calls f<int>, i.e., T is int 
f(ci);    // now calls f<const int>, i.e., T is const int 
f(*pci);   // also calls f<const int>, i.e., T is const int 

Este comportamiento es una noticia vieja, aplicando como lo hace tanto para C + +98 y C++ 03. El comportamiento de las variables auto correspondiente es, por supuesto, nuevo en 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 

Ya que se puede conservar la CV-calificador si el tipo es una referencia o puntero, puede hacer:

auto& my_foo2 = GetFoo(); 

en lugar de tener que especificar como const (mismo ocurre con volatile).

Editar: cuanto a por qué auto deduce el tipo de retorno de GetFoo() como un valor en lugar de una referencia (que era su principal pregunta, lo siento), considere esto:

const Foo my_foo = GetFoo(); 

Lo anterior se creará una copiar, ya que my_foo es un valor. Si auto devolviera una referencia lvalue, lo anterior no sería posible.

+5

No explicó por qué también se elimina el calificador de referencia. –

+3

@Tomalak Geret'kal: ¿Quieres decir por qué han decidido hacer esto? Tiene sentido, ¿no? Considere esto: 'Foo my_foo = GetFoo();' y ese 'GetFoo()' no devolvió un tipo const. Sería lo mismo que: 'auto my_foo = GetFoo();'. Si también se incluye automáticamente la referencia, no podrá hacer lo anterior. – someguy

+5

No me digas; ponlo en tu respuesta. –

Cuestiones relacionadas