0

我正在尝试编译以下代码片段。请检查我最后得到的错误。

#include "Tree.h"

template <class T>
CNode<T>* CNode<T>::GetChild(const T& kData)
{
    for( std::vector< CNode >::iterator it = m_vChildren.begin(); it!= m_vChildren.end(); ++it)
    {
        if(*it== kData)
        {
           return &(*it);
        }
    }
}

Tree.h(头文件):

#include "../include_m.h"
#include <vector>

template <class T>
class CNode
{
 public:
    CNode(const T& kData)
    {
        m_Data = kData;
    }

    void AddChildNode(const CNode& kcChildNode);
    void DeleteChildNode(const T& kData);
    void GetChildNode(const T& kData) const;
    void Print();

 private:
    T                       m_Data;
    std::vector<CNode>      m_vChildren;

    CNode * GetChild(const T& kData);
};

这无法编译并出现以下错误:

g++ -o tree Tree.cpp 
Tree.cpp: In member function ‘CNode<T>* CNode<T>::GetChild(const T&)’:
Tree.cpp:12: error: expected `;' before ‘it’
Tree.cpp:12: error: ‘it’ was not declared in this scope
4

2 回答 2

2

你所缺少的只是一个typenamebefore std::vector< CNode >::iterator。由于CNode<T>::GetChild是模板化上下文,编译器无法知道std::vector< CNode >::iterator是类​​型成员还是值成员。例如,您可以将std::vector<CNode<int> >whereiterator定义为类字段的模板特化。您需要使用typename关键字来解决这种歧义。

在相关说明中,您需要template关键字的情况更加棘手,在这里可能值得一提,请考虑:

template <class T>
struct C {
   template <class U>
   void memfunc();
};

template <class T>
void func() {
   C<T> c;
   c.template memfunc<int>();
}

您需要在最后一行出现奇怪的template关键字,因为由于与您的问题类似的原因,编译器无法知道该成员实际上是 class 的所有专业化中的模板方法C。您收到的错误消息也很奇怪,每次都让我感到困惑。

其他答案也有关于在.cpp文件中包含模板定义的相关点。您可能应该听从他们的建议并将定义移动到.h文件中。但是,在某些情况下,您需要在.cpp文件中定义模板。例如,该方法可能只在同一个.cpp文件中使用。或者,您可能想要控制希望使用显式实例化来实例化模板化成员函数的类型。您可以通过以下方式实现:

template class CNode<int>; // explicitly instantiate CNode<int> 
template CNode<double>* CNode<double>::GetChild(const double& kData); // explicitly instantiate only the GetChild method for CNode<double>

这样,每当您更改方法的实现时,您就不必重新编译.cpp包含的每个文件。tree.hGetChild

于 2013-03-11T06:45:43.343 回答
0
  1. 您不能将.cpp文件与模板类一起使用。一切都必须在.h.
  2. CNode在标头中使用对来指示返回类型、放置在std::vectors 和参数中的值。这些必须改成CNode<T>.

这是因为CNode它本身并不作为一个类存在,而是一个用于在编译时创建的类的模板。对于放置在其中的每种类型<T>;在编译时创建一个新类。

含义CNode<X>与 不同类CNode<Y>,并且CNode在二进制/可执行文件中根本不存在。

这意味着您永远不能引用 CNode 或其成员,而不提供<T>.

于 2013-03-11T06:45:08.460 回答