为什么我会得到“无法解析的外部符号"?使用模板时出错?

2022-01-11 00:00:00 templates linker c++

当我使用模板为类编写 C++ 代码并在源 (CPP) 文件和头 (H) 文件之间拆分代码时,在链接最终可执行文件,尽管目标文件已正确构建并包含在链接中.这里发生了什么,我该如何解决?

When I write C++ code for a class using templates and split the code between a source (CPP) file and a header (H) file, I get a whole lot of "unresolved external symbol" errors when it comes to linking the final executible, despite the object file being correctly built and included in the linking. What's happening here, and how can I fix it?

推荐答案

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

Templated classes and functions are not instantiated until they are used, typically in a separate .cpp file (e.g. the program source). When the template is used, the compiler needs the full code for that function to be able to build the correct function with the appropriate type. However, in this case the code for that function is detailed in the template's source file and hence unavailable.

由于所有这些,编译器只是假设它是在其他地方定义的,并且只插入对模板化函数的调用.在编译模板的源文件时,程序源中使用的特定模板类型并没有在那里使用,因此它仍然不会生成函数所需的代码.这会导致无法解析的外部符号.

As a result of all this the compiler just assumes that it's defined elsewhere and only inserts the call to the templated function. When it comes to compile the template's source file, the specific template type that is being used in the program source isn't used there so it still won't generate the code required for the function. This results in the unresolved external symbol.

对此可用的解决方案是:

The solutions available for this are to:

  1. 包括完整的定义中的成员函数模板的头文件并且没有模板的源文件,
  2. 定义所有的成员函数模板的源文件为"inline" (更新:[这不适用于 Visual Studio 2017+]),或
  3. 定义成员模板源中的函数使用导出"关键字.不幸的是,这不受支持很多编译器.(更新:这已从 C++11 的标准中删除.)
  1. include the full definition of the member function in the template's header file and not have a source file for the template,
  2. define all the member functions in the template's source file as "inline" (Update: [this does not work on Visual Studio 2017+]), or
  3. define the member functions in the template's source with the "export" keyword. Unfortunately this isn't supported by a lot of compilers. (Update: this has been removed from the standard as of C++11.)

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

Both 1 and 2 basically address the problem by giving the compiler access to the full code for the templated function when it is attempting to build the typed function in the program source.

相关文章