This is a followup to C++ templates: prevent instantiation of base template
I use templates to achieve function overloading without the mess of implicit type conversions
When compiling main.cpp, there's no way for the compiler to know which template specializations may exist in some other compilation unit -- so there's no way to flag this error at compile time, you have to wait until link time.
I don't believe it's possible to do what you want. See these FAQs for more info:
How can I avoid linker errors with my template functions?
How can I avoid linker errors with my template classes?
It seems to produce a linker error even if you don't put it in the separate file.
However, to produce a compiler error for other instantiations, implement the function and use a compile-time assertion, e.g
#include <boost/static_assert.hpp>
template <class T> T f(T)
{
//assert some type-dependent "always-false" condition,
//so it won't be triggered unless this function is instantiated
BOOST_STATIC_ASSERT(sizeof(T) == 0 && "Only long or bool are available");
}
template<> long f(long v) { return -v; }
template<> bool f(bool v) { return !v; }
int main()
{
//f(100);
f(100L);
f(false);
}
And just for general information, C++0x has a much more elegant way to deal with it:
template <class T> T f(T) = delete;
template<> long f(long v) { return -v; }
template<> bool f(bool v) { return !v; }
The best way is to implement that basic template with something invalid (not illegal) C++ code. For example,
template<class T> T f(T v) { return v.Default_Implementation_Not_Available; }
This error will be compile time; and it's generated only when you instantiate any version other than 'long' & 'bool'. If you don't instantiate 'int' version, compilation will go fine.