Item 42: Understand the Two Meanings of typename

Two use cases: To use in template declaration and to give compiler a hint that this name is a type.

Since compiler will assumes a name is not a type unless you tell it otherwise (this happens to nested dependent names):

template<typename T>
void foo()
{
  // Tell compiler that T::bar is a type.
  // And this is defining a local variable,
  // not a multiplication.
  typename T::bar* x;
  ...
}

Why only to nested dependent names? Because a class may define a nested class or static data member. And a nested dependent name T::bar could be either one of them (you have to tell compiler it is which one of them).

Note: But you are not allowed to precede typename in a list of base classes or in a member initialization list (this is inconsistent, but …).

template<typename T>
class Foo: public Bar<T>::Nested {  // typename not allowed
 public:
  Foo(int x): Bar<T>::Nested(x) {}  // typename not allowed
}

By the way, there is no difference between using class or using typename in template declaration.

// No difference at all; just a matter of taste.
template<class T> class Foo;
template<typename T>class Foo;

(But compilers actually aren’t very strict about these rules.)

Creative Commons License
This blog by Che-Liang Chiou is licensed under a Creative Commons Attribution 4.0 International License.