tags:

views:

128

answers:

3

When I try and compile the following code...

#include <vector>

template <class T> void DoNothing()
{
    std::vector<T>::iterator it;
}

int main(int argc, char**argv)
{
    return 0;
}

g++ says:

test.cpp:5: error: expected `;' before ‘it’

And I don't understand why this is a problem. If I replace it with std::vector<int>::iterator, say, it works fine as expected.

As you can see i'm not instantiating the function, so g++ must have a problem with the template definition itself, but I can't see how its invalid.

Thanks for any advice about whats going on.

NB I'm actually trying to write a templated class and having issues with a map rather than a vector, but this is the simplest test case for my problem.

A: 

Does typename std::vector<T>::iterator it; work?

EDIT: change template to typename ... got my keywords mixed up.

eduffy
+7  A: 

You need to use the typename keyword because the std::vector<T>::iterator type is dependent on the template parameter:

template <class T> void DoNothing()
{
    typename std::vector<T>::iterator it;
}

It can actually be confusing when you need to use typename and when you don't need it (or are even not permitted to use it). This article has a decent overview:

Michael Burr
Thanks! The article helps also, though It still seems strange that the interpretation isn't left until instantiation.
DaedalusFall
Thanks for the answer Michael, it helped me too. I've had the same question for a long time and now I know when to use the typename keyword. The article sure helped.
Gastón
While some dependent names need typename in front of them, others don't need it. C++03, for example, says that in a template: template<class T> struct F { class A { }; void f() { A a; } }; the type-name "A" is dependent, since it is equivalent to saying F::A and F<T>::A (and affects name-lookup at instantiation context). But another paragraph then says if a type-member is named using an unqualified name, typename is not required. See 14.6/6 and the new paragraph 14.6.1/2d in c++03. And C++1x introduces the concept of a member-of-the-current-instantiation where then typename is not required...
Johannes Schaub - litb
I found that in addition, http://womble.decadentplace.org.uk/c++/template-faq.html is a very nice template faq to help with these confusing rules
Johannes Schaub - litb
+1  A: 

I agree it is confusing. Without the typename keyword, the name would be considered a static member. The book C++ Templates by Vandevoorde and Josuttis explains this in detail.

Borbus