我无法在C ++中使用模板进行编译

时间:2009-06-26 01:13:37

标签: c++ templates

我用g ++编译了以下线索

#include <iostream>
#include <string>
using namespace std;
template<class T>
class Node<const char*>{
private:
  string x_;
  Node* next_;
public:
  Node (const char* k, Node* next):next_(next),x_(k){}
  string data(){return x_;}
  Node *get_next(){return next_;}
};

$ g++ -c node01.cc
node01.cc:5: error: ‘Node’ is not a template

怎么了? 我是c ++的招手

2 个答案:

答案 0 :(得分:6)

您正在混淆声明和实例化。声明模板时,不要在其名称后面立即指定类型。相反,声明如下:

template<class T>
class Node {
private:
  const T x_;
  Node *next_;
public:
  Node (const T& k, Node *next) : x_(k), next_(next) { }
  const T& data(){return x_;}
  Node *get_next(){return next_;}
};

您的原始声明还会混淆stringconst char *和应该使用T的通用类型。对于这样的模板,您可能希望让用户定义成员的类型(x_)。如果您明确声明它为const char *string,则通过限制用户可用于T的内容而失去通用性。

请注意,我将实例变量的类型,构造函数的参数和data()的返回类型更改为T

当您实际实例化模板类型的变量时,您可以提供具体的类型参数例如

int main(int argc, const char **argv) {
    Node<char*> *tail = new Node<char*>("tail", NULL);
    Node<char*> *node = new Node<char*>("node", tail);
    // do stuff to mynode and mytail
}

每当您在模板声明之外编写模板名称Node时,在您为参数T提供值之前,它都不会完整。如果您只是说Node,编译器将不知道您想要的节点。

上面有点冗长,所以当你真正使用它时,你也可以使用typedef简化它:

typedef Node<char*> StringNode;
int main(int argc, const char **argv) {
    StringNode *tail = new StringNode("tail", NULL);
    StringNode *node = new StringNode("node", tail);
    // do stuff to mynode and mytail
}

现在您已经构建了两个节点的链接列表。您可以使用以下内容打印出列表中的所有值:

for (StringNode *n = node; n; n = n->get_next()) {
    cout << n->data() << endl;
}

如果一切顺利,这将打印出来:

node
tail

答案 1 :(得分:2)

您的班级声明应如下所示:

template<class T>
class Node{
private:
  T x_;
  Node* next_;
public:
  Node (const T& k, Node* next):next_(next),x_(k){}
  T data(){return x_;}
  Node *get_next(){return next_;}
};

请注意我删除了对stringconst char *的所有引用,并将其替换为通用类型T。由于它是模板化的,因此您的类不应引用任何特定类型,而应根据通用T类型执行所有操作。

稍后在声明const char *变量时指定Node。或者它可以是任何其他类型,而不仅仅是const char *。关键是,当您声明Node类时,您只需在代码中使用泛型类型T,而无需引用任何特定类型。只有在实际使用Node时才指定特定类型。

Node<const char *> stringNode("foo", NULL);
Node<int>          intNode(5, NULL);

这使我们能够对Node类进行单一定义,但能够使用它来创建数据为字符串的节点和数据为整数的节点。万岁模板!