6

Is it possible to somehow forbid using templated function for types for which specialization was not explicitly written. I mean something like that

template <typename T>
void foo(){}

template <>
void foo<int>(){}

int main(int argc, char* argv[]){
    foo<int>(); //ok
    foo<char>(); //Wrong - no specialized version for char.
}

I cannot skip generic version of function, cause then compiler says, that foo is not a template function when i try to specialize. I could simply write something that does not compile in generic function, and add some comment explaining why, but this would be quite non-informative. What i would like to do, is to be able to directly cause compiler to go with error like "foo() is not defined".

j_kubik
  • 6,062
  • 1
  • 23
  • 42

2 Answers2

15

Sure: just don't define it and you'll get a linker error if you try to use it:

template <typename T>
void foo(); // not defined

template <>
void foo<int>() { }

Alternatively, you can use some variation of a static assert to give a "nicer" compile-time error. Here is an example using the C++0x static_assert. Note that you must make the false value dependent upon the template parameter, otherwise the static_assert may be triggered when the template is parsed.

template <typename T>
struct dependent_false { enum { value = false }; };

template <typename T>
void foo()
{
    static_assert(dependent_false<T>::value, "Oops, you used the primary template");
}

Note that it's usually best not to specialize function templates. Instead, it is better to delegate to a specialized class template:

template <typename T>
struct foo_impl
{
    static_assert(dependent_false<T>::value, "Oops, you used the primary template");
};

template<>
struct foo_impl<int>
{
    static void foo() { }
};

template <typename T>
void foo()
{
    return foo_impl<T>::foo();
}
James McNellis
  • 348,265
  • 75
  • 913
  • 977
4

Sure, just don't supply definition for the default generic template.