Original Post
🔒 Locked
C++ template problem
Advertisement
Looks fine on it's own. What version of g++ are you using? Also post a couple of the lines before that line as well as the declaration of TemplatedStructure.
template<typename T> struct mwCacheItem{ T* item; std::string name; mwCacheItem (T* theItem, std::string theName) : item(theItem), name(theName) {} ~mwCacheItem () { if (item) delete item; }}; template<typename T> class mwCacheTemplate{private: std::vector< mwCacheItem<T> > itemList;public: T* query (std::string name) { std::vector< mwCacheItem<T> >::const_iterator iter; for (iter = itemList.begin(); iter != itemList.end(); iter++) { if ((*iter).name == name) return (*iter).item; }...that's the relevent part i think
Assuming T is a yet-unspecified template parameter, std::vector< TemplatedStructure<T> >::const_iterator is a dependent name (it is a member of a class template which hasn't been fully specialized yet). C++ compilers assumes that a dependent name refers to a static variable unless you use the keyword typename.
typename std::vector< TemplatedStructure<T> >::const_iterator iter;
typename std::vector< TemplatedStructure<T> >::const_iterator iter;
Well? Don't you want to specify a valid template parameter?
Id est:
std::vector< TemplatedStructure<T> >::const_iterator iter;
Turns into:
std::vector< TemplatedStructure<int> >::const_iterator iter;
T is not a type. (edit: as fruny touches upon, at least not typically)
jfl.
[edit] And beaten... Oh well. Besides, fruny's reply is better.
Id est:
std::vector< TemplatedStructure<T> >::const_iterator iter;
Turns into:
std::vector< TemplatedStructure<int> >::const_iterator iter;
T is not a type. (edit: as fruny touches upon, at least not typically)
jfl.
[edit] And beaten... Oh well. Besides, fruny's reply is better.
The reason it is so is because you could very well do:
If I write foo<double>::f, the compiler can go and check what f is in foo<double> - a type. But if I write:
the compiler cannot check if the syntax is correct without deciding if foo<T>::bar should be a static variable (in which case the syntax is incorrect) or a nested type (in which case it is correct). The default choice is to treat it as a static variable. The addition of typename causes the compiler to treat it as a type.
Templates are syntax-checked where they are defined, but checks that depend on actually knowing the template pararameters (like, is a<b legal when a and b are of type quux) are obviously deferred until the point at which the template is used (which means that your program may compile even though some functions have errors if you don't actually call those functions).
template<class T> class foo{ typedef T f;};template<> class foo<int>{ static int f;};If I write foo<double>::f, the compiler can go and check what f is in foo<double> - a type. But if I write:
template<class T> class bar{ foo<T>::bar b;};the compiler cannot check if the syntax is correct without deciding if foo<T>::bar should be a static variable (in which case the syntax is incorrect) or a nested type (in which case it is correct). The default choice is to treat it as a static variable. The addition of typename causes the compiler to treat it as a type.
template<class T> class bar{ typename foo<T>::bar b;};Templates are syntax-checked where they are defined, but checks that depend on actually knowing the template pararameters (like, is a<b legal when a and b are of type quux) are obviously deferred until the point at which the template is used (which means that your program may compile even though some functions have errors if you don't actually call those functions).
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement