Why do we need typename here?

In general, C++ needs typename because of the unfortunate syntax [*] it inherits from C, that makes it impossible without non-local information to say -- for example -- in A * B; whether A names a type (in which case this is a declaration of B as a pointer to it) or not (in which case this is a multiplication expression -- quite possible since A, for all you can tell without non-local information, could be an instance of a class that overloads operator* to do something weird;-).

In most cases the compiler does have the non-local information needed to disambiguate (though the unfortunate syntax still means the low-level parser needs feedback from the higher-level layer that keeps the symbol table info)... but with templates it doesn't (not in general, though in this specific case it might be technically illegal to specialize a std::list<T> so that its ::iterator is NOT a type name;-).

[*] not just my opinion, but also the opinion of Ken Thompson and Rob Pikes, currently my colleagues, who are busy designing and implementing a new programming language for internal use: that new programming language, while its syntax is mostly C-like, does NOT repeat C's syntax design errors -- it the new language (like e.g. in good old Pascal), syntax is sufficient to distinguish identifiers that must name a type from ones that must not;-).


If you are talking of typename used with std::list<T>::iterator:

The typename is used to clarify that iterator is a type defined within class std::list<T>. Without typename, std::list<T>::iterator will be considered a static member. typename is used whenever a name that depends on a template parameter is a type.


I think in general you need both the typename/class T in the class declaration as well as function definitions because you can define full/partial template specifications for function definitions. Ie. you could specialize your remove function for ints, strings, whatever it happens to be. So in this case you're telling the compiler "This is the general template, for any type" then later you might define the same function specified for only integers.


typename is needed in your declaration of 'it' because otherwise the compiler doesn't know that it's a type declaration rather than an expression.

According to this page, "Use the keyword typename if you have a qualified name that refers to a type and depends on a template parameter."