C++ Migration Guide

Resolving Type Names

The C++ standard has new rules for determining whether an identifier is the name of a type. The following example illustrates the new rules:


typedef int S;
class B { ... typedef int U; ... }
template< class T > class C : public B {
    S    s; // OK
    T    t; // OK
    U    x; // 1 No longer valid
    B::U y; // 2 No longer valid
    T::V z; // 3 No longer valid
};

The new language rules state that no base class is searched automatically to resolve type names in a template, and that no name coming from a base class or template parameter class is a type name, unless it is declared to be so with the keyword typename.

The first invalid line (1) in the code example tries to inherit U from B as a type without the qualifying class name and without the keyword typename. The second invalid line (2) correctly modifies the type with the name of the base class, but the typename modifier is missing. The third invalid line (3) uses type V coming from the template parameter, but omits the keyword typename. The definition of s is valid because the type doesn't depend on a base class or member of a template parameter. Similarly, the definition of t is valid because it uses type T directly, a template parameter which must be a type.

The following code shows the correct implementation:


typedef int S; 
class B { ... typedef int U; ... } 
template< class T > class C : public B {
    S             s; // OK
    T             t; // OK
    typename B::U x; // OK
    typename B::U y; // OK
    typename T::V z; // OK
};