使用模板时,为什么会出现"未解析的外部符号"错误?

dla*_*nod 92 c++ linker templates

当我使用模板为类编写C++代码并在源(CPP)文件和标题(H)文件之间拆分代码时,在链接最终可执行文件时会出现大量"未解析的外部符号"错误,尽管目标文件正确构建并包含在链接中.这里发生了什么,我该如何解决?

dla*_*nod 112

模板化的类和函数在使用之前不会被实例化,通常在单独的.cpp文件中(例如程序源).使用模板时,编译器需要该函数的完整代码才能使用适当的类型构建正确的函数.但是,在这种情况下,该函数的代码在模板的源文件中详细说明,因此不可用.

作为所有这些的结果,编译器只是假定它在别处定义并且仅将调用插入到模板化函数中.在编译模板的源文件时,程序源中使用的特定模板类型不会在那里使用,因此它仍然不会生成该函数所需的代码.这导致未解析的外部符号.

可用的解决方案是:

  1. 在模板的头文件中包含成员函数的完整定义,并且没有模板的源文件,
  2. 将模板源文件中的所有成员函数定义为"inline",或
  3. 使用"export"关键字在模板源中定义成员函数.不幸的是,很多编译器都不支持.(更新:从C++ 11开始,这已从标准中删除.)

1和2基本上解决了这个问题,它使编译器在尝试在程序源中构建类型化函数时访问模板化函数的完整代码.

  • 你应该改写(2).不知道你的意思 (10认同)
  • 在(3)中,您有输入错误.你可能意味着关键词,而不是键盘.我不知道如何将函数定义为'inline'会有所帮助.您需要将它们放在标题中,或使用您需要的类型显式实例化模板. (4认同)
  • 我有同样的问题,这不回答它...我不知道为什么这被接受为答案.包括成员函数的完整定义有效,但是,在我看来,它表示我们的程序缺乏安全性,并且通常是导致无组织代码的不良做法. (2认同)
  • @ JohannesSchaub-litb如果每个东西都需要在头文件(defination)中,那么`.cpp`文件的用途是什么? (2认同)

sho*_*osh 13

另一个选择是将代码放在cpp文件中,并在同一个cpp文件中添加模板的显式实例化,以及您希望使用的类型.如果您知道您将提前使用它几种类型,这将非常有用.

  • @jbx错了.模板编程不会重复自己.如果你写的东西恰好是超级通用的,非常好的,对你有好处,但这绝不是必要的.如果它允许我只写一个类或函数而不是2,它就实现了它的目的.即使是标准容器也不是独立的类型,它们依赖于默认的c'tor和移动c'tor之类的东西. (5认同)
  • 所以基本上说*f*******u*模块化,重用,单一责任和关注点分离......以及通用编程的全部要点,即通用类可以用于任何你想要的类型*没有模板类事先知道*它将用于什么? (4认同)
  • @jbx我说'对于像`basic_string <T>`这样的东西,你只会在`char`或`wchar_t`中使用它,所以如果把所有的实现都放在头文件中是一个问题,那么实例化它cpp是一种选择.代码是你的命令,反之亦然. (4认同)