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

compile header files defines a template class which also includes other header files

本文关键字:还包括 文件 其他 一个 文件定义 编译      更新时间:2023-10-16

只是想明确一点:这与我们必须在头文件中定义模板类的函数的问题有不同

UPDATE:如果您需要真正的源代码,可以在这里下载: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,并调用函数

// 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.cpp中的内容包含在list.h中,然后只编译test.cpp,它就可以工作了。但我认为这不是一个好主意。

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

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的规则实际上与template的规则几乎相同:无论何时使用inline函数,都必须提供其实现。