2010-12-13 10 views
5

No sé por qué no se puede compilar este código. He probado en Visual C++ 2010 y gcc con -std = C++ 0x. Alguien da alguna sugerencia? gracias!Pregunta sobre el colapso de referencia de C++ 0x

template<typename T> 
class Foo 
{ 
public: 
void test(const T&){cout<<"const";} 
void test(  T&){cout<<"non const";} 
}; 

int main() 
{ 
int a; 
Foo<int&> f; 
} 

error de compilación: 'vacío Foo :: prueba (T)': función miembro ya definido o se declara

pero ¿por qué esto puede ser compilado?

template<typename T> void foo(const T&){cout<<"const"; } 
template<typename T> void foo(T&){cout<<"non const"; } 
int main() 
{ 
    int a; 
    foo<int&>(a); 
} 

i'v leer C++ 0x artículo dijo: T & & == T &, por lo que T const & & == T const &?

Respuesta

8

Este:

Foo<int&> f; 

da lugar a esta instanciación:

class Foo<int&> 
{ 
public: 
void test(int&); 
void test(int&); 
}; 

const aplicado a un tipo que es una referencia es un no-op. Compararla con una función miembro no estática que opera en un miembro de datos de referencia:

struct A { 
    int &ref; 

    // valid: const member function doesn't treat "ref" as "const int&". 
    void operate() const { 
    ref = 0; 
    } 
}; 

usted tiene que pasar a intFoo<...> para lograr su objetivo.

13

i'v read c++0x article said: T& & ==T& , so const T& & == const T& ?

En realidad, eso no tiene mucho sentido. En mi humilde opinión, es mejor poner esto en una tabla:

T  T&  const T  const T& 
--------------------------------------- 
int  int& const int const int& 
int& int& int&   int& 
     (1)  (2)   (1+2) 

1: Reference collapsing in action 
2: const applies to the reference and is therefore ignored 

Si T es ya una referencia (segunda fila) de la const en const T se aplica a la referenciay no al árbitro. Pero una referencia es inherentemente constante en el sentido de que no se puede hacer que se refiera a otro objeto después de la inicialización, por lo que un const simplemente se ignora aquí. Puedes pensar que es "colapsar const". ;-)

1

Para la segunda pregunta, las dos funciones tienen el mismo tipo de parámetro, y ambas son plantillas (si una es una plantilla, la otra es una función sin plantilla, la resolución de sobrecarga elegirá la posterior)), por lo que la resolución de sobrecarga elegirá la plantilla que es más especializada. En general, const T & es un tipo más especializado que T &, por lo que se llama a la primera función de plantilla.