2

When I put all the source in one file, the program successfully builds. However when I split them into header files, I get a link error.

The main of my program: //C++_Class_Templates.cpp

#include <iostream>
#include <vector>
#include "Queue.h"

using namespace std;

//Usage for C++ class templates
void main()
{
     MyQueue<int> q;
     q.Add(1);
     q.Add(2);
}

The Queue.h looks like this

#pragma once
#include <vector>

template <typename T>
class MyQueue
{
     std::vector<T> data; 
   public:
     void Add(T const &);
     void Remove();
     void Print();

};

and the Queue.cpp looks like this:

#include "Queue.h"

template <typename T> void MyQueue<T> ::Add(T const &d)
{
     data.push_back(d);
}

When I try to build it, I get this error:

 1>main.obj : error LNK2019: unresolved external symbol "public: void __thiscall
 MyQueue<int>::Add(int const &)" (?Add@?$MyQueue@H@@QAEXABH@Z) referenced in function _main
razlebe
  • 7,134
  • 6
  • 42
  • 57
unj2
  • 52,135
  • 87
  • 247
  • 375
  • You didn't "split into header files". You split into multiple **implementation** files, which make the template definition unavailable when it was needed. – Ben Voigt Feb 02 '11 at 00:02
  • 1
    possible duplicate of [Link error using templates](http://stackoverflow.com/questions/550219/link-error-using-templates) – Nemanja Trifunovic Feb 02 '11 at 00:05
  • @Nemanja : I can't delete it. – unj2 Feb 02 '11 at 01:16
  • You don't have to delete it, don't worry :) – Nemanja Trifunovic Feb 02 '11 at 15:08
  • I add this comment 11 years later, just in case someone else lands here after searching for template compilation problem due to the separation of declaration and definition in different files. There is a simple solution, in case the reason why you separate declaration and definition is not an attempt to improve the compilation time, but just for human readability : just add an include of the definition file at the end of your template declaration file, like `#include Queue.cpp` at the end of `Queue.h`. I don't know if there are scenarios where it fails, but in my case it works fine :) – hugogogo Jun 03 '22 at 11:40

2 Answers2

11

The short answer is: "you don't."

The longer answer is: well, it's basically the same as the short answer. For more information, see the C++ FAQ Lite entry "Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file?" Except for certain limited-use scenarios (like when you have a small set of known arguments with which you will use the template and you can explicitly instantiate it with those types), the definition of the template must be available when you try to use it.

James McNellis
  • 348,265
  • 75
  • 913
  • 977
1

Separating declaration and definition for templates is not trivial.

The compiler must see the definition to be able to compile a specialization but it must also know the parameters to use. C++ was designed to be compiled one "compile unit" at a time and those two parts (the definition and the parameters) must be visible at the same time.

So either you put all a list of all specializations you will need in the implementation file of the template or you put the whole definition in the .h file. Both of those two solutions have however drawbacks.

See this answer to the same problem you are facing for a more complete explanation.

Community
  • 1
  • 1
6502
  • 112,025
  • 15
  • 165
  • 265