Also, also, it was Gorka rather than Bakul who called me out for being rude, so apologies to both.
But this is my favourite section from Herr Stroustrup's book - from Section C.13.5 - although the following section (C.13.6 Template as a Qualifier) is also good for a laugh. Right, I'll shut up and stop trolling after this. However, this does not allow us to write: template<class C>void f(C&v) { C::iterator i=v.begin();//error //... } Unfortunately, the compiler isn’t required to be psychic, so it doesn’t know that C::iterator is the name of a type. In the previous example, the compiler could look at the declaration of vector<> to determine that the iterator in vector<T>::iterator was a type. That is not possible when the qualifier is a type parameter. Naturally, a compiler could postpone all checking until instantiation time where all information is available and could then accept such examples. However, that would be a nonstandard language extension. Consider an example stripped of clues as to its meaning: template<class T>void f(T&v) { T::x(y); // error? } Is T::x a function called with a nonlocal variable y as its argument? Or, are we declaring a variable y with the type T::x perversely using redundant parentheses? We could imagine a context in which X::x(y) was a function call and Y::x(y) was a declaration. The resolution is simple: unless otherwise stated, an identifier is assumed to refer to something that is not a type or a template. If we want to state that something should be treated as a type, we can do so using the typename keyword: template<class C>void f(C&v) { typename C::iterator i=v.begin(); //... } The typename keyword can be placed in front of a qualified name to state that the entity named is a type. In this, it resembles struct and class. The typename keyword can also be used as an alternative to class in template declarations. For example: template<typename T>void f(T); Being an indifferent typist and always short of screen space, I prefer the shorter: template<class T>void f(T);