为什么我应该使用"typename"关键字进行以下定义?

ero*_*gol 1 c++ pointers typename

template <typename dataType>
**typename** List<dataType>::Node* List<dataType>::find(int index){
    Node *cur = head;
    for(int i = 0; i < index; i++){
        cur = cur->next;
    }
    return cur;
}
Run Code Online (Sandbox Code Playgroud)

如果我不使用它,我会收到以下错误:

need ‘typename’ before ‘List<dataType>::Node’ because ‘List<dataType>’ is a dependent scope
Run Code Online (Sandbox Code Playgroud)

所以我阅读了wiki条目,但我没有得到该特定示例背后的原因.

Tri*_*dle 7

因为,就像错误消息所说的那样,List<dataType>::Node依赖名称,即依赖于模板参数的名称.想象一下你有这样的事情:

struct A {
    typedef float t;
};

struct B {
    static int t;
};

template <typename T>
void func()
{
    T::t * x; // pointer declaration, or multiplication? It depends...
}
Run Code Online (Sandbox Code Playgroud)

在这里,A::tB::t都是有效的C++表达式,但意味着完全不同的事情:首先是一个类型,而第二个是一个值.现在,当编译器首先解析模板函数时func()- 在进行任何类型替换之前检查它是否在语法上是正确的 - 它必须尝试并决定什么T::t * x意思.显然,有两种方法可以解析它,因此编译器必须决定采取哪种方法.

在某些情况下,编译器有足够的"上下文"来确定您是否引用类型,但在许多情况下(例如此示例),则没有.当它无法决定时,它假设你在谈论一个值 - 所以上面会(希望)给你一个关于变量x未知的错误.如果您希望T::t被视为一种类型,则需要使用typename关键字明确地告诉它.