编译头文件定义了一个模板类,该类还包括其他头文件

时间:2013-12-02 22:22:03

标签: c++ templates hyperlink g++

只是要说清楚:与我们必须在头文件中定义模板类的功能的问题不同

更新:如果您需要真正的源代码,可以在此处下载:https://Near@bitbucket.org/Near/compile_error.git

我实现了一个双列表类。

// list.h //
class list {
  //...
  void insert(...);
};

// list.cpp //
#include "list.h"
void list::insert(...) {
  ...
}

我还实现了一个包含list.h的模板类

// template_class.h //
#include "list.h"
template<class T>
class temp_class {
  list l;
  void func();
}

void temp_class::func() {
  //...
  l.insert(...);
}

现在我编写一个test.cpp文件,其中包含template_class.h并调用func函数

// test.cpp //
#include "template_class.h"
int main() {
  temp_class<int> t;
  t.func();
  return 0;
}

我像这样编译

g++ test.cpp list.cpp -o test

编译器抱怨test.cpp:“未定义引用插入”。 为什么它不能工作?如何解决这个错误?


仅供参考:如果我在list.h中的list.cpp中包含内容并且只编译test.cpp,它就可以了。但我认为这不是一个好主意。

1 个答案:

答案 0 :(得分:0)

编译代码时,我会立即收到警告:

list_double.h:14:15: warning: inline function ‘void list_double_node::list_double_insert_first(list_double_node*)’ used but never defined [enabled by default]
void inline list_double_insert_first(list_double_node* entry);

也就是说,您的代码实际上类似于此SSCCE

// list.h
class list {
public:
  inline void insert(int);
};

// list.cpp
#include "list.h"
void list::insert(int) {
}

// template_class.h
#include "list.h"
template<class T>
class temp_class {
  list l;
public:
  void func();
};
template <class T>
void temp_class<T>::func() {
  l.insert(17);
}

// test.cpp
#include "template_class.h"
int main() {
  temp_class<int> t;
  t.func();
  return 0;
}

修复方法是:删除inline或在标题中定义函数。 inline的规则实际上与模板的规则几乎相同:只要使用inline函数,就必须提供它的实现。