No. Headers are included, sources compiled.
When you compile "main.cpp", the compiler does not see verbatim
1 2 3 4 5 6 7 8 9
|
#include "Math.h"
#include <iostream>
using namespace std;
int main()
{
Math<int> BO(23,56);
cout << BO.addition() << endl;
}
|
The
preprocessor did see that file, but did insert each #include, recursively. Therefore, the compiler did see:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
// contents of header "iostream" and whatever it includes,
// because the Math.h has #include
using namespace std;
template <class T>
class Math{
public:
Math(T a, T b){
Num1 = a;
Num2 = b;
}
T addition();
private:
T Num1;
T Num2;
};
// main.cpp had include iostream here, but if iostream has
// include guards, nothing is added here because it has
// already been inserted earlier
using namespace std;
int main()
{
Math<int> BO(23,56);
cout << BO.addition() << endl;
}
|
Line 29 calls Math<int>::addition(). If that would be a concrete function, then compiler would assume that the object file of some other
compilation unit has the compiled code for it and the linker will handle it.
However, there exists only template for the function and the compiler should form the source of Math<int>::addition() from template and then compile it. Alas, there is no template in this compilation unit.
You don't have to write the template implementations directly into the header. You can have them in separate file and let the header include it:
1 2 3 4 5 6 7 8
|
#ifndef unique-foo-header-id
#define unique-foo-header-id
template <typename T>
T foo( T );
#include "foo_impl"
#endif // unique-foo-header-id
|
You can name the foo_impl as you wish, but:
* Extension .cpp would hint that it is separately compiled, which it is not
* Extension .h is quite good, maybe you wish to clearly separate implementations from regular headers
* Development environment may or may not be confused by everything else (like .hpp or .icc)