std::vector and template problem...

Started by
16 comments, last by Oxyd 15 years, 11 months ago
Inside template definitions, there are two kinds of types: dependent types and non-dependent types. Dependent types depend on the template arguments. So if you had a template with a T type argument then T would be a dependent type, but std::vector<T> is also a dependent type because it depends on what the definition of T is. Examples of non-dependent types would be like int, char or pretty much anything that doesn't contain T.

When using the :: operator on a dependent type, the compiler is supposed to assume that the identifier is a non-type identifier like a static member variable or member function name. So std::vector<T>::iterator will be assumed to be a non-type. In order for iterator to be treated as a type, you need to specify the typename keyword.
Advertisement
Quote:Original post by Shakedown
Quote:Original post by SiCrane
You're probably missing a typename keyword
typename vector<T*>::iterator


Could someone explain why this needs to be typename'd? I'm not completely familiar with typenames, and I would have written this same for loop (without a typename) and would have had the same problem. Why doesn't that work just as an iterator for the for loop?


Because in the expression vector<T>::iterator, T is a template parameter — that means, vector<T> is not really a type, it is a template from which a type will be generated. So the compiler can’t know what vector<T>::iterator will be at the moment it processes the enclosing class template — in which case it defaults to considering iterator a member object. This then causes a syntax error as the compiler sees for (someVariable it = ... ). By giving the typename there, you tell the compiler it should treat the symbol iterator as a type, rather than an object.

This typename stuff is one of the things that take a while to get, but the general (and inaccurate) rule is: When you do something like SomeType<T>::SomeNestedType, where T is a template parameter, you need to use typename there.
Quote:Original post by Oxyd
Because in the expression vector<T>::iterator, T is a template parameter — that means, vector<T> is not really a type, it is a template from which a type will be generated.

Close, but not quite. vector<T> is unambiguously a type, and by itself needs no typename.
Ahh, yes, that makes total sense as it's inside a template definition. Thanks for the clarification guys!
Quote:Original post by Rasmadrak
In my code I do have a semicolon after the class declaration, and "using namespace std".

That is a bad idea.

Your ResourceManager class is a template class, so I'm safe to assume, that it is defined in a header file.

Having "using namespace std" in a header file is a bad idea, because every source file that include the header, will also include the "using namespace std", which isn't always desired. So, just to be safe, I would suggest to explicitly add "std::" everywhere, instead of "using namespace std" in a header file.

Just a tip. ;)

You can use "using namespace std;" inside of functions also. That
whey you don't need to type "std::" everywhere, any you don't get the
nasty defined in header file side effect.
Quote:Original post by mzeo77
You can use "using namespace std;" inside of functions also.

Would this insert std:: at compile time or would there be any kind of overhead at runtime?

Quote:Original post by Oxyd
And, regardless that, the std::vector object will not necessarily be on the stack — it will be in the same storage as the enclosing ResourceManager-type object (i.e., if you do new ResourceManager then the vector will be allocated in the free store even without newing it manually).

I didn't know that! I guess not using pointers inside the class would increase performance as well if a lot of new/delete is going on, would it not?

Paulius Maruska:
I'll remove the namespace as soon as I convert my resourcemanager into a class of it's own. Currently it's under development and currently labeled a "pet project" :)

Thanks again all!
"Game Maker For Life, probably never professional thou." =)
Quote:Original post by Rasmadrak
Quote:Original post by mzeo77
You can use "using namespace std;" inside of functions also.

Would this insert std:: at compile time or would there be any kind of overhead at runtime?

It only affects visibility of the symbols — and symbols are entirely compile-time thing. It will not have any impact on runtime at all.

Quote:Original post by Rasmadrak
I didn't know that! I guess not using pointers inside the class would increase performance as well if a lot of new/delete is going on, would it not?

new and delete are quite costly operations, yes.

This topic is closed to new replies.

Advertisement