Think about it this way.
Say you have
1 2 3 4 5 6 7 8 9 10
|
template< typename T >
class Adder {
// Just an example
public:
Adder( T v );
Adder operator+( const Adder& rhs ) const;
private:
T value;
};
T> Adder<T>::operator+( const Adder
|
in a header file, and then you put all the code in a .cpp file.
Suppose that all operator+ does is
|
return Adder( value + rhs.value );
|
Now when the compiler compiles the .cpp file, what is T? T could be almost any type -- int, short, char, float, double, even std::string. T could be more than one type: perhaps in your program somewhere you use Adder<int> whereas in another place you use Adder<float> and in a third place you use Adder<std::string>.
How's the compiler to know when compiling Adder.cpp? Short answer: it can't. Longer answer: it can, provided that in Adder.cpp you instantiate Adder with every different type your program will attempt to instantiate Adder with, but in practice most programmers don't do that for reasons of maintainability.
It matters because when the compiler is compiling the body of operator+, if T is of an integral type, it can generate an integer ADD instruction, but if T is of floating point type, then it must generate a floating point ADD instruction, and if T is std::string, it has to call
std::string::operator+( const std::string& ) const
instead. (etc, etc.)
Basically, the only point at which the compiler knows what T is, is when you instantiate it, for example in main.cpp or some other .cpp file. Only at that point can the compiler actually generate the assembler/machine code for the functions in Adder. But in order to do that, the compiler must be able to "see" the complete implementation of the class. The only way for the compiler to see the implementation is to #include it. Since it is never recommended to #include .cpp files, that leaves you with putting the complete implementation in the header file.