'Templates and .cpp files

I am learning C++ and it hasn't been an enjoyable experience (compared to Java or VBA at least). I have the following code:

//This is in a number.h file
  #pragma once
  template <class T>
  class number{
        public: 
               T value1, value2, result; 
        public: 
               T add();
               number(T value1_in, T value2_in);
  };

 //This is in a number.cpp file
   template <class T>
   number<T>::number(T value1_in, T value2_in){
              value1 = value1_in;
              value2 = value2_in;
   }

   template <class T>
   T number<T>::add(){
   result = value1 + value2; 
   return result; 
   }

 //This is in main.cpp
   #include "number.h"
   #include <iostream>
   using namespace std;

   int main(){
       int a = 2, b =3;

       number<int> n1(a,b);
       cout << n1.add();
       system("pause");
       return EXIT_SUCCESS;
  }

Which of course gives me an error. Even though I am pretty sure it should work. More specifically I get a linker error. After 3 hours of looking at this I decided to include number.cpp in main.cpp and that magically made it work. What the hell is going on? I thought I only need to include the header file (I wrote a matrix class with a bunch of linear solvers for different algorithms before this and only included header files in the whole project). Is this C++ specific or compiler specific? (I am using Dev-C++ 4.9.9.2 which has Mingw I guess)



Solution 1:[1]

Templated classes or functions always need to stay in the header file.

The reason is that whenever you instantiate a template, the preprocessor (inside compiler) generates new code for exactly that kind of instantiation (e.g. number<double>). That's why the classes number<double> and number<int> will not share any relationship: They will be two completely different classes although both were generated from the same template.

For the compiler to be able to generate this code, it must know the whole template definition, not only its declaration. That's why a template needs to stay in the header in full.

Including the cpp file in your main.cpp did the trick, as it effectively became a header.

Solution 2:[2]

In C++, templates are just as their name suggests: templates for a class, function etc. As the concrete type of the template parameter is not known in advance, and the compiled object code depends on the actual parameter, they are not getting compiled (as normal classes and functions) until you use them in any other source file and the compiler gets to know what type should it substitute into the template parameter.

That's why all functions must be defined and implemented in the header file. See the last section of this documentation or the answers for this similar question for further explanation.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Community