How to define a template class and split it into multiple files?

I wrote a simple template for testing. It compiles without any errors, but when I try to use it in main (), it gives some linker errors.



main.cpp

#include <iostream> #include "MyNumber.h" int wmain(int argc, wchar_t * argv[]) { MyNumber<float> num; num.SetValue(3.14); std::cout << "My number is " << num.GetValue() << "." << std::endl; system("pause"); return 0; } 



Mynumber.h

 #pragma once template <class T> class MyNumber { public: MyNumber(); ~MyNumber(); void SetValue(T val); T GetValue(); private: T m_Number; }; 



Mynumber.cpp

 #include "MyNumber.h" template <class T> MyNumber<T>::MyNumber() { m_Number = static_cast<T>(0); } template <class T> MyNumber<T>::~MyNumber() { } template <class T> void MyNumber<T>::SetValue(T val) { m_Number = val; } template <class T> T MyNumber<T>::GetValue() { return m_Number; } 



When I create this code, I get the following linker errors:

Error 7 Console Demo C: \ Development \ IDE \ Visual Studio 2010 \ SAVE \ Grand Solution \ X64 \ Debug \ Console Demo.exe 1 Error LNK1120: 4 unresolved external

Error 3 Console Demo C: \ Development \ IDE \ Visual Studio 2010 \ SAVE \ Grand Solution \ Console Demo \ main.obj error LNK2019: unresolved external symbol "public: __cdecl MyNumber :: ~ MyNumber (void)" (?? 1? $ MyNumber @M @@ QEAA @XZ) referenced by the wmain function

Error 6 Console Demo C: \ Development \ IDE \ Visual Studio 2010 \ SAVE \ Grand Solution \ Console Demo \ main.obj error LNK2019: unresolved external symbol "public: __cdecl MyNumber :: MyNumber (void)" (?? 0? $ MyNumber @M @@ QEAA @XZ) referenced by the wmain function

Error 4 Console Demo C: \ Development \ IDE \ Visual Studio 2010 \ SAVE \ Grand Solution \ Console Demo \ main.obj Error LNK2019: Unresolved External Symbol "public: float __cdecl MyNumber :: GetValue (void)" (? GetValue @? $ MyNumber @M @@ QEAAMXZ) referenced by the wmain function

Error 5 Console demo C: \ Development \ IDE \ Visual Studio 2010 \ SAVE \ Grand Solution \ Console Demo \ main.obj error LNK2019: unresolved external symbol "public: void __cdecl MyNumber :: SetValue (float)" (? SetValue @? $ MyNumber @M @@ QEAAXM @Z) referenced by the wmain function

But if I leave main () empty, I don't get any linker errors.

What is wrong with my template? What am I doing wrong?

+4
source share
3 answers

You must explicitly create a template for each template parameter used.

Ie, add the following line to the end of the MyNumber.cpp file:

 template class MyNumber<float>; 

Thus, the linker will be able to find all the instances of templates he needs.

See also Moving templates from header files .

+1
source

You cannot implement a template in a cpp file. You need to define class methods in the header file itself. See Why can't I separate the class definition of my templates from its declaration and put it in a .cpp file? for more information.

+1
source

Well, you should actually use export , but almost no compiler will implement it. You can get around this by extracting non-generic code into separate functions and defining them in separate files.

+1
source

Source: https://habr.com/ru/post/1333283/


All Articles