Why do I get “unresolved external symbol” errors when using templates? [duplicate]

牧云@^-^@ 提交于 2020-01-05 19:41:41

问题


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?


回答1:


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. 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.)

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.




回答2:


Another option is to put the code in the cpp file and in the same cpp file add explicit instantiations of the template with the types you expect to be using. This is useful if you know you're only going to be using it for a couple of types you know in advance.




回答3:


For each file that include the .h file you should be to insert both lines:

#include "MyfileWithTemplatesDeclaration.h"
#include "MyfileWithTemplatesDefinition.cpp"

sample

#include "list.h"
    #include "list.cpp" //<---for to fix bug link err 2019



    int main(int argc, _TCHAR* argv[])
    {
        list<int> my_list;
        my_list.add_end(3);
    .
    .
    } 

also, you dont forget to place your declaration class among centinel constants

#ifndef LIST_H
#define LIST_H
#include <iostream>
.
.
template <class T>
class list
{
private:
    int m_size,
        m_count_nodes;
    T m_line;
    node<T> *m_head;
public:
    list(void);
    ~list(void);
    void add_end(T);
    void print();
};
#endif


来源:https://stackoverflow.com/questions/13308547/getting-around-a-lnk2019-c-template-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!