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);
}