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

时间:2014-01-20 09:30:49

标签: 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;
}

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

need ‘typename’ before ‘List<dataType>::Node’ because ‘List<dataType>’ is a dependent scope

所以我读了wiki entry,但我不明白这个特定例子背后的原因。

1 个答案:

答案 0 :(得分: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...
}

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

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