1
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;
}

If I don't use that I get following error:

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

So I read the wiki entry but I do not get the reason behind that particular example.

erogol
  • 11,182
  • 28
  • 90
  • 144
  • `This code looks like it should compile, but it is incorrect because the compiler does not know if T::bar is a type or a value.` – Gasim Jan 20 '14 at 09:33
  • Rule of thumb: take the rightmost `::`; if the thing to the right of it is a type, and the thing to the left of it depends on template parameters in any way, use `typename`. – Angew is no longer proud of SO Jan 20 '14 at 09:33

1 Answers1

7

Because, like the error message says, List<dataType>::Node is a dependent name, that is, one that depends on the template parameter. Imagine you had something like this:

struct A {
    typedef float t;
};

struct B {
    static int t;
};

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

Here, A::t and B::t are both valid C++ expressions, but mean completely different things: the first is a type, and the second is a value. Now, when the compiler first parses the template function func() -- to check whether it's syntactically correct, before doing any type substitution -- it has to try and decide what T::t * x means. Clearly, there are two possible ways to parse it, so the compiler has to decide which to take.

In some circumstances there is enough "context" for the compiler to work out whether you're referring to a type or not, but in many cases (such as this example), there isn't. When it can't decide, it assumes you're talking about a value -- so the above would (hopefully) give you an error about the variable x being unknown. If you wanted T::t to be treated as a type, you'd need to tell it so explicitly, using the typename keyword.

Tristan Brindle
  • 15,036
  • 2
  • 31
  • 79