C ++模板typename迭代器

C++ template typename iterator

考虑以下头文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <typename T> struct tNode
{
    T Data;                      //the data contained within this node
    list<tNode<T>*> SubNodes;       //a list of tNodes pointers under this tNode

    tNode(const T& theData)
    //PRE:  theData is initialized
    //POST: this->data == theData and this->SubNodes have an initial capacity
    //      equal to INIT_CAPACITY, it is set to the head of SubNodes
    {
        this->Data = theData;
        SubNodes(INIT_CAPACITY);   //INIT_CAPACITY is 10
    }

};

现在考虑另一个文件中的一行代码:

1
list<tNode<T>*>::iterator it();  //iterate through the SubNodes

编译器给了我这个错误消息:Tree.h:38:17: error: need ‘typename’ before ‘std::list*>::iterator’ because ‘std::list*>’ is a dependent scope

我不知道为什么编译器会冲我大喊大叫。


list*>::iterator中,您有一个依赖名称,即依赖于模板参数的名称。

因此,编译器不能检查list*>(此时没有它的定义),因此它不知道list*>::iterator是静态字段还是类型。

在这种情况下,编译器假定它是一个字段,因此在您的例子中,它会产生语法错误。要解决这个问题,只需在声明之前放置一个typename,告诉编译器它是一个类型:

1
typename list<tNode<T>*>::iterator it

首先,正如其他答案已经指出的那样,嵌套到依赖类型中的类型名需要用typename关键字进行前缀。

当模板完全专用时,不需要该关键字,这意味着list*>::iterator不需要typename,但当外部类仍然依赖于模板参数T时,必须存在typename

1
2
3
4
template <typename T> void foo() {
  list<tnode<int>*>::iterator it1; // OK without typename
  typename list<tnode<T>*>::iterator it2; // typename necessary
}

第二,即使有typename

1
typename list<tNode<T>*>::iterator it();

声明将声明函数,而不是迭代器。拆下()


list*>::iterator是一个依赖名称,依赖于模板参数的类型。要声明该变量,需要使用typename关键字:

1
typename list<tNode<T>*>::iterator it = ...;

这里提供了关于上述答案的更多回传。

C++类型名称关键字的描述

我有一个不同但类似的问题,我想为子节点typedef一个迭代器,其中包含:

1
typedef std::vector<NodeType*>::iterator ChildIterator;

这给了我同样的编译器错误。有了这里的建议和上述链接的帮助,我的问题的解决方案是使用

1
typedef typename std::vector<NodeType*>::iterator ChildIterator;

相反。