1

Possible Duplicate:
Where and why do I have to put the “template” and “typename” keywords?
c++ template typename iterator

The following code will not compile:

#include <iostream>
#include <set>
using namespace std;

template<class T>
void printSet(set<T> s){
    set<T>::iterator it;
}

int main(int argc, char** argv){
    set<int> s;
    printSet<int>(s);
    return 0;
}

I get an error saying:

set.cpp: In function ‘void printSet(std::set<T, std::less<_Key>, std::allocator<_CharT> >)’:
set.cpp:7: error: expected `;' before ‘it’
set.cpp: In function ‘void printSet(std::set<T, std::less<_Key>, std::allocator<_CharT> >) [with T = int]’:
set.cpp:12:   instantiated from here
set.cpp:7: error: dependent-name ‘std::set<T,std::less<_Key>,std::allocator<_CharT> >::iterator’ is parsed as a non-type, but instantiation yields a type
set.cpp:7: note: say ‘typename std::set<T,std::less<_Key>,std::allocator<_CharT> >::iterator’ if a type is meant

What did I do wrong? I feel like I've hardly written anything, and already C++ gives me this scary message.

In case it is helpful, it looks like, if I comment out the line with the iterator, there are no errors. However, all the examples I've seen online so far seem to declare iterators this way. I think.

Community
  • 1
  • 1
math4tots
  • 7,575
  • 11
  • 49
  • 89

1 Answers1

10

Precede your declaration with the keyword typename, thusly:

typename set<T>::iterator it;

You need to do this whenever you refer to a type that is dependent upon a template argument. In this case, iterator is dependent on T. Otherwise, the compiler has difficulty trying to figure out what iterator is, whether it's a type, or a static member or something else. (well, technically, it doesn't try to figure it out, its decision is already made, it just happens to be wrong)

Note that if you have a concrete type, for example:

set<int>::iterator it;

The typename is not necessary.

Benjamin Lindley
  • 95,516
  • 8
  • 172
  • 256