Zagnieżdżone szablony z zakresem zależnym

79

Co to jest zakres zależny i jakie jest znaczenie nazwy typu w kontekście następującego błędu?

$ 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;
}
user383352
źródło

Odpowiedzi:

124

Kompilator dokładnie powiedział ci, co masz zrobić. Napisz typenamewcześniej ptrModel<std::vector<Data> >::Type, tak:

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

Powodem tego wymogu jest to, że kompilator nie robi w tym momencie wiem, czy ptrModel<std::vector<Data> >::Typeopisuje zmienną składową lub typu zagnieżdżonego. Nie może nawet postać, która przez patrząc na definicji ptrModel, ponieważ nie może być specjalizacja ptrModeldla std::vector<Data>gdzieś w programie, że nie dostał na które jednak zmiany, które z tych rzeczy ::Typeodnosi się do. Więc musisz to wyraźnie powiedzieć.

Nazwa ptrModel<std::vector<Data> >::Typema „zakres zależny”, ponieważ znajduje się w zakresie zależnym od instancji szablonu.

Tyler McHenry
źródło
6
W porządku, ale czy to prawda, że ​​wpisywanie zmiennej składowej nie ma sensu?
user383352
5
Tak, ale to niekoniecznie pomaga ze względu na pewne szczegóły dotyczące przetwarzania szablonów przez kompilator. Zobacz zaakceptowaną odpowiedź na to pytanie: stackoverflow.com/questions/642229/…
Tyler McHenry
5
Uważam również, że ta odpowiedź jest bardzo pomocna, gdy po raz pierwszy natrafiłem na ten błąd i koncepcję.
Drew Noakes