C++ template specialization without default function
To get a compile-time error implement it as:
template<typename T>
T GetGlobal(const char *name) { T::unimplemented_function; }
// `unimplemented_function` identifier should be undefined
If you use Boost you could make it more elegant:
template<typename T>
T GetGlobal(const char *name) { BOOST_STATIC_ASSERT(sizeof(T) == 0); }
C++ Standard guarantees that there is no such type which has sizeof equal to 0, so you'll get a compile-time error.
As sbi suggested in his comments the last could be reduced to:
template<typename T>
T GetGlobal(const char *name) { char X[!sizeof(T)]; }
I prefer the first solution, because it gives more clear error message (at least in Visual C++) than the others.
Though it is an old and outdated question, it may worth noting that C++11
had solved this issue using deleted functions:
template<typename T>
T GetGlobal(const char *name) = delete;
template<>
int GetGlobal<int>(const char *name);
UPDATE
This will not compile under MacOS llvm 8
.
It is due to a still hanging 4 years old defect (see this bug report).
The following workaround will fit the issue (using a static_assert
construct).
template<typename T>
T GetGlobal(const char *name) {
static_assert(sizeof(T) == 0, "Only specializations of GetGlobal can be used");
}
template<>
int GetGlobal<int>(const char *name);
UPDATE
Visual studio 15.9 has the same bug. Use the previous workaround for it.
If you don't implement it, you'll at least get a linker error. If you want a compile-time error, you could do this with class templates:
template<typename T>
struct GlobalGetter;
template<>
struct GlobalGetter<int> {
static int GetGlobal(const char *name);
};
template<>
struct GlobalGetter<double> {
static double GetGlobal(const char *name);
};
template<typename T>
T GetGlobal(const char *name)
{
return GlobalGetter<T>::GetGlobal(name);
}