Officially, what is typename for?

Viewed 90005

On occasion I've seen some really indecipherable error messages spit out by gcc when using templates... Specifically, I've had problems where seemingly correct declarations were causing very strange compile errors that magically went away by prefixing the typename keyword to the beginning of the declaration... (For example, just last week, I was declaring two iterators as members of another templated class and I had to do this)...

What's the story on typename?

8 Answers

I think all of the answers have mentioned that the typename keyword, is used in two different cases:

a) When declaring a template type parameter. e.g.

template<class T> class MyClass{};        // these two cases are
template<typename T> class MyNewClass{};  // exactly the same.

Which there is no difference between them and they are EXACTLY the same.

b) Before using a nested dependent type name for a template.

template<class T>
void foo(const T & param)
{
   typename T::NestedType * value; // we should use typename here
}

Which not using typename leads to parsing/compilation errors.

What I want to add to the second case, as mentioned in Scot Meyers book Effective C++, is that there is an exception of using typename before a nested dependant type name. The exception is that if you use the nested dependant type name either as a base class or in a member initialization list, you should not use typename there:

template<class T>
class D : public B<T>::NestedType               // No need for typename here
{
public:
   D(std::string str) : B<T>::NestedType(str)   // No need for typename here
   {
      typename B<T>::AnotherNestedType * x;     // typename is needed here
   }
}

Note: Using typename for the second case (i.e. before nested dependent type name) is not needed since C++20.

Related