Propagándose ‘typedef’ a partir de la clase derivada para ‘template’

Estoy tratando de definir la clase base, que contiene solo typedef.

template class A { public: typedef std::vector Vec_t; }; template class B : public A { private: Vec_t v; // fails - Vec_t is not recognized }; 

¿Por qué en BI recibo un error de que Vec_t no es reconocido y necesito escribirlo explícitamente?

 typename A::Vec_t v; 

Creo que esta pregunta está duplicada, pero no puedo encontrarla ahora. El Estándar C ++ dice que debes calificar completamente el nombre de acuerdo con 14.6.2 / 3:

En la definición de una plantilla de clase o miembro de una plantilla de clase, si una clase base de la plantilla de clase depende de un parámetro de plantilla, el scope de clase base no se examina durante la búsqueda de nombres no calificados en el punto de definición de la clase plantilla o miembro o durante una instanciación de la plantilla o miembro de la clase.

UPD: encontré duplicado finalmente: aquí está .

Hay algo llamado nombres dependientes y no dependientes en el caso de las plantillas.

Si el nombre depende del parámetro de la plantilla T, su nombre dependiente y otros que no dependen del parámetro T son nombres independientes .

Aquí está la regla: el comstackdor no busca en las clases base dependientes (como A) cuando busca nombres no dependientes (como Vec_t). Como resultado, el comstackdor no sabe que existen, y mucho menos son tipos.

El comstackdor no puede asumir que Vec_t es un tipo hasta que conoce T porque existe una especialización potencial de A donde A:: Vec_t es un miembro de datos

Entonces la solución es usar typename

  typename A::Vec_t v; ← good 

Te recomiendo que revises este https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-types .

Enlace antiguo (roto): http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18

Porque el comstackdor no está seguro de que Vec_t nombre un tipo. Por ejemplo, A podría estar especializado para que T=int no tenga ese typedef particular.

Necesita calificar explícitamente el uso de Vec_t porque el comstackdor no sabe de dónde viene Vec_t .

No puede asumir nada sobre la estructura de A, ya que la plantilla de clase A puede estar especializada. La especialización puede incluir un Vec_t que no sea un typedef, o puede que ni siquiera incluya un miembro Vec_t en absoluto.

Vec_t no es un nombre dependiente, y el comstackdor necesita saber de qué se trata sin instanciar ninguna plantilla (clase base en este caso). Realmente no es diferente de:

 template  class X { std::string s; } 

Aquí también el comstackdor necesita saber acerca de std :: string incluso si X no está instanciado, ya que el nombre no depende del argumento de la plantilla T (en la medida que el comstackdor pueda suponer).

Con todo, los typedefs en una clase base de plantilla parecen bastante inútiles para su uso en la clase derivada. Sin embargo, los typedefs son útiles para el usuario.

Este concepto puede asociarse con la forma en que usamos std::vector . Por ejemplo, si tenemos un std::vector Foo . Ahora, decidimos usar cualquiera de sus tipos de miembros, digamos un iterator . En este escenario, mencionamos explícitamente

 std::vector::iterator foo_iterator; 

De manera similar, en su caso, para usar un miembro público escriba Vec_t de la template class A , necesita declararlo explícitamente como

 A::Vec_t v; OR A::Vec_t int_type;