2012-04-16 8 views
5

a.h¿Por qué no puedo usar la variable de la clase padre que es la clase de plantilla?

template <typename T> 
class A 
{ 
    public: 
    int a; 
} 

b.h

template <typename T> 
class B : public A<T> 
{ 
    public: 
    int f(); 
} 

template <typename T> 
int B<T>::f() 
{ 
    int t; 
    t = this->a; //Okay 
    t = a //Error 
    return 0; 
} 

¿Por qué ocurre error al no uso this->?

¿Puedo omitir this-> usando algún método?

(I solucionado algunos errores)

+0

Joachim Pileborg le dio la respuesta. Además de eso, el código proporcionado tiene otros problemas que le impiden compilar. – Anonymous

+0

¿Es este el código real?No hay puntos y coma al final después de las definiciones de clase y el operador de ámbito para 'int B : f()' es incorrecto más no hay punto y coma en la línea de error. – hmjd

+0

oh, es solo un error de tipeo. Lo arreglé. –

Respuesta

11

Hay dos fases en instancias de plantilla ("Fase Dos de búsqueda de nombres").

En la primera fase, todos los nombres no dependientes se resuelven (se busca). En la segunda fase, los nombres dependientes se resuelven.

Un nombre dependiente es un nombre que depende de un parámetro de plantilla, por ejemplo .:

template <typename T> 
void foo() { 
    x = 0; // <- Non-dependent, nothing in that refers to "T". 
       // Thus looked up in phase 1, therefore, an 'x' must be 
       // visible. 

    T::x = 0; // <- Dependent, because it depends on "T". 
       // Looked up in phase 2, which is when it must be visible. 
} 

Ahora, se escribe:

t = this->a; //Okay 
t = a //Error 

Esto es exactamente lo que he descrito. En el término correcto, t se busca en la fase 2, porque this depende de un parámetro de plantilla.

El término erróneo se busca en la fase 1, porque nada en ese nombre depende de un parámetro de plantilla. Pero en la fase 1, no a es visible, porque el compilador no puede introspeccionar las plantillas de clase base en la fase 1, porque las plantillas pueden especializarse y en el momento de instanciación, que pueden ser remotas de la declaración de plantilla primaria, otra especialización que no tiene a, puede ser visible.

Ejemplo:

template <typename T> 
    struct Base { 
    }; 


    template <typename T> 
    struct Derived : Base<T> { 
     void foo() { 
      this->a = 0; // As is valid. `this->a` is looked up in phase 2. 
     } 
    }; 


    template <> struct Base<int> { 
     int a;    
    }; 


    int main() 
    { 
      // The following declarations trigger phase 2 lookup. 

      Derived<int> di; // valid, because a later specialized 
           // Base<int> is used and all symbols 
           // are resolved. 

      Derived<float> df; // not valid 
    } 

Por cierto, una vez que he escrito this-> is not only a matter of style en mi blog muy baja frecuencia.

+0

Un nombre dependiente es un nombre que no depende de un parámetro de plantilla -> Un nombre dependiente es un nombre que depende de un parámetro de plantilla:) – czxyl

+0

@czxyl: Casi media década para descubrir este error: D Gracias por la pista:) –

1

B es una plantilla, por lo que sus nombres no son dependientes y, por lo tanto, deben buscarse cuando se define la plantilla, no cuando se crea una instancia. Sin embargo, en el momento de la definición de la plantilla, los nombres dependientes no se conocen (puede haber especializaciones de la plantilla de clase base A que no se han visto hasta ahora), el compilador no puede resolver el nombre no calificado para la clase base. Usted puede llevar el nombre en el ámbito actual a través this-> calificación, prefijándolo con A<T>:: o con una declaración using:

template <typename T> 
class B : public A<T> 
{ 
    public: 
    using A<T>::a; 
    int f(); 
}; 

También tenga en cuenta que cuando faltan punto y coma después de las declaraciones de clase y la línea marcada con el comentario // Error.

+0

"No se conocen los nombres dependientes" -> Esto no tiene sentido en el lenguaje de C++. Un nombre puede ser dependiente o no, p. con typename T, 'A :: x' es un nombre dependiente,' x' no lo es. Puede tener sentido para usted, como programador, que 'x' sea un nombre dependiente, pero técnicamente,' x' no es un nombre dependiente. –

+0

-1: "sus nombres no son dependientes y por lo tanto deben buscarse" -> Esto es incorrecto. Puede haber nombres de miembros que sean dependientes. Ejemplo: http://ideone.com/zIa7k –

+0

-1: 'this->' no tiene nada que ver con el alcance. –

Cuestiones relacionadas