Plantillas anidadas con alcance dependiente

79

¿Qué es el alcance dependiente y cuál es el significado de typename en el contexto del siguiente error?

$ make
g++ -std=gnu++0x main.cpp
main.cpp:18:10: error: need 'typename' before 'ptrModel<std::vector<Data> >::Type' because 'ptrModel<std::vector<Data> >' is a dependent scope
make: *** [all] Error 1


/*
 * main.cpp
 */

#include <vector>
#include <memory>

template<typename T>
struct ptrModel
{
 typedef std::unique_ptr<T> Type;
};


template<typename Data>
struct ptrType
{
 typedef ptrModel< std::vector<Data> >::Type Type;
};

int main()
{
 return 0;
}
usuario383352
fuente

Respuestas:

124

El compilador le dijo exactamente qué hacer. Escribe typenameantes ptrModel<std::vector<Data> >::Type, así:

 typedef typename ptrModel<std::vector<Data> >::Type Type;

los razón de este requisito es que el compilador no sabe en este momento si ptrModel<std::vector<Data> >::Typedescribe una variable miembro o un tipo anidado. Ni siquiera puede darse cuenta de eso al mirar la definición de ptrModelporque podría haber una especialización de ptrModelen std::vector<Data>algún otro lugar del programa al que aún no ha llegado a qué cambios se ::Typerefiere. Entonces necesitas decirlo explícitamente.

El nombre ptrModel<std::vector<Data> >::Typetiene un "ámbito dependiente" porque está en un ámbito que depende de la instanciación de una plantilla.

Tyler McHenry
fuente
6
De acuerdo, pero ¿no es cierto que no tiene sentido escribir una variable miembro?
user383352
5
Sí, pero eso no ayuda necesariamente debido a algunos detalles sobre cómo el compilador analiza las plantillas. Vea la respuesta aceptada a esta pregunta: stackoverflow.com/questions/642229/…
Tyler McHenry
5
También encontré que esta respuesta es muy útil cuando me encuentro con este error y este concepto por primera vez.
Drew Noakes