It seems that I cannot put the implementation code for comp in hello.cpp
. Is that true?
Usually, yes; most templates need to be defined in every translation unit in which they're used, so they usually need to be defined in a header.
However, it looks like you're trying to explicitly instantiate it for one (or some set of) types, while disallowing it for others. In that case, you need to declare it in the header:
// hello.h
template<typename T>
bool comp( T first, T second );
define and instantiate it in a source file:
// hello.cpp
template<typename T>
bool comp( T first, T second )
{
return first < second;
}
template bool comp(int, int);
and use the instantiated specialisations in any file that includes the header:
// main.cpp
std::cout << std::boolalpha << comp(10, 12) << std::endl; // fine
// std::cout << std::boolalpha << comp(2.2, 3.3) << std::endl; // link error
why the second line in the main.cpp still compiles?
In your example, the template definition is still available (in the header) to implicitly instantiate any specialisations needed. So the second line instantiates it for double
and compiles happily. Moving the template definition into a separate source file prevents that.