Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

block non-specialized template c++

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".

like image 838
j_kubik Avatar asked Aug 04 '11 19:08

j_kubik


1 Answers

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();
}
like image 166
James McNellis Avatar answered Sep 19 '22 04:09

James McNellis