2009-10-26 18 views
9

Tengo una base de código anterior aquí, donde utilizaron variables de miembro protegidas. Se puede discutir si esta es una buena idea o no. Sin embargo, el código debe haberse compilado bien con gcc3. que tienen una barra de clase de plantilla derivado que utiliza protegida miembro de x de plantilla de clase Foo igual queMiembro protegido de acceso de una clase en una clase derivada

template <class Something> class Foo { 
public: 
// stuff... 
protected: 
    some::type x; 
} 

template <class Something> Bar : Foo<Something> { 
public: 
    void cleanup(); 
} 

Y en la declaración del método de limpieza() no es algo que se hace con x

template <class Something> void Bar<Something>::cleanup() { 
    doSomeThingCleanUpLike (x); 
} 

Esto hace no funciona con gcc4, aunque debería haber funcionado con gcc3. Funciona cuando lo cambio a

doSomeThingCleanUpLike (this->x); 

¿Por qué es así?

+1

El término "clase de plantilla" suele ser la fuente de confusión. El término correcto es "plantilla de clase", porque la cosa es una plantilla para clases. No es una clase. Editaría tu pregunta, pero posiblemente sea una de las razones por las que te confundiste. – MSalters

+1

La definición de su función de "limpieza" no es conforme. pierde el tipo de devolución y los argumentos de plantilla para "Barra". Claro que así es como está en tu código? –

+0

gracias litb. Lo cambie. el nivel de cafeína no era lo suficientemente alto como para detectarlo. También se cambió a "plantilla de clase". Sin embargo, si su clase de plantilla o plantilla de clase no debería afectar el problema. El término se usa informalmente mucho. – GeeF

Respuesta

13

La expresión x utilizada en la clase derivada es, según las reglas del estándar, no dependiente de ningún parámetro de plantilla de la clase derivada. Debido a esto, la búsqueda ocurre en el contexto de la definición de la plantilla y no en el punto de uso/instanciación. Aunque la clase base de la plantilla de la plantilla parece ser visible, dado que es una clase de plantilla, la instanciación particular que podría utilizarse podría involucrar plantillas especializadas, por lo que la definición de la plantilla de la clase base no se puede usar para buscar nombres.

Al cambiar la expresión a this->x, la convierte en una expresión dependiente (this en una plantilla de clase siempre depende de los parámetros de la plantilla). Esto significa que la búsqueda ocurrirá en el contexto de creación de instancias en cuyo punto la clase base es completamente conocida y sus miembros son visibles.

+0

+1 en el uso del término adecuado: * nombres dependientes */* no dependientes *. –

6

Cuando se define la plantilla derivada, el compilador solo conoce el nombre de la clase de plantilla base pero no sus detalles, por lo que el compilador no sabe que la clase derivada tiene un miembro heredado. Para decirle al compilador de la existencia del miembro, use this->, tal como lo hizo.

En realidad, es un duplicado de this question.

+1

Es importante tener en cuenta que agregar 'this->' no es un ritual, sino una forma de convertir un nombre no dependiente en uno dependiente. Ver la respuesta de Charles. –

+0

Buena captura, esa pregunta _tiene_ un título malo. Corregido ahora. – MSalters

Cuestiones relacionadas