The rule is: typename
has to be used whenever a name that depends on a template parameter is a type. There are clear cases where it's needed, consider
template <typename T>
class Foo {
typename T::type * p;
//...
};
Here, the second typename
is used to indicate that type
is a type defined within class T
. Thus, p
is a pointer to the type T::type
.
Without typename
, type
would be considered a member of class T
. So the expression:
T::type * p
would be a multiplication of the type
member of class T
with p
.
Similarly, the rule is: .template
, ->template
or ::template
must be used when accessing a template member that uses a template parameter. Consider:
p->template SomeMethod<int>(x);
without the use of template
, the compiler does not know that the <
token is not less-than but the start of a template argument list.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…