C++模板typename迭代器

Cod*_*lus 39 c++ templates iterator typename

请考虑以下头文件:

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
    }

};
Run Code Online (Sandbox Code Playgroud)

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

list<tNode<T>*>::iterator it();  //iterate through the SubNodes
Run Code Online (Sandbox Code Playgroud)

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

我不知道为什么编译器会为此大喊大叫.

aka*_*ppa 66

list<tNode<T>*>::iterator,您有一个从属名称,即一个依赖于模板参数的名称.

因此,编译器无法检查list<tNode<T>*>(此时它没有定义),因此它不知道list<tNode<T>*>::iterator是静态字段还是类型.

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

typename list<tNode<T>*>::iterator it
Run Code Online (Sandbox Code Playgroud)


AnT*_*AnT 21

首先,正如已经提到的其他答案一样,嵌套在依赖类型中的类型名称需要在typename关键字前面添加.

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

template <typename T> void foo() {
  list<tnode<int>*>::iterator it1; // OK without typename
  typename list<tnode<T>*>::iterator it2; // typename necessary
}
Run Code Online (Sandbox Code Playgroud)

其次,即使typename

typename list<tNode<T>*>::iterator it();
Run Code Online (Sandbox Code Playgroud)

声明将声明一个函数,而不是迭代器.删除().


mfo*_*ini 5

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

typename list<tNode<T>*>::iterator it = ...;
Run Code Online (Sandbox Code Playgroud)