Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function templates: Different specializations with type traits

Considering class templates, it is possible to provide template specializations for certain types of groups using type traits and dummy enabler template parameters. I've already asked that earlier.

Now, I need the same thing for function templates: I.e., I have a template function and want a specialization for a group of types, for example, all types that are a subtype of a class X. I can express this with type traits like this:

std::enable_if<std::is_base_of<X, T>::value>::type

I thought about doing it this way:

template <typename T, typename ENABLE = void>
void foo(){
    //Do something
}

template <typename T>
void foo<T,std::enable_if<std::is_base_of<A, T>::value>::type>(){
    //Do something different
}

However, this does not work since partial specialization is not allowed for function templates. So how to do it then? Maybe a default parameter with the type trait as type? But how does the code look like then?

like image 943
gexicide Avatar asked Sep 03 '12 14:09

gexicide


People also ask

What is function template specialization?

The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.

What are the differences between function template and template function?

"A function template is a template that is used to generate functions. A template function is a function that is produced by a template. For example, swap(T&, T&) is a function tem-plate, but the call swap(m, n) generates the actual template function that is invoked by the call."

What is explicit template specialization?

Explicit (full) specializationAllows customizing the template code for a given set of template arguments.

How can you differentiate a function template from a class template?

For normal code, you would use a class template when you want to create a class that is parameterised by a type, and a function template when you want to create a function that can operate on many different types.


2 Answers

Overloads:

void foo_impl(T, std::false_type);

void foo_impl(T, std::true_type);

foo(T t) { foo_impl(t, std::is_base_of<A, T>()); }
like image 83
Kerrek SB Avatar answered Sep 18 '22 10:09

Kerrek SB


The closest to what you're asking is enable_if on the return type:

template<typename T> typename std::enable_if<std::is_same<T, int>::value>::type foo();
template<typename T> typename std::enable_if<std::is_same<T, char>::value>::type foo();

However, dispatching to a helper function or class is likely to be more readable and efficient.

Helper function:

template<typename T> void foo_helper(std::true_type);
template<typename T> void foo_helper(std::false_type);
template<typename T> void foo() { foo_helper(std::is_same<T, int>()); }

Helper class:

template<typename T, bool = std::is_same<T, int>::value> struct foo_helper {};
template<typename T> struct foo_helper<T, true> { static void foo(); };
template<typename T> struct foo_helper<T, false> { static void foo(); };
template<typename T> void foo() { foo_helper<T>::foo(); }
like image 22
ecatmur Avatar answered Sep 22 '22 10:09

ecatmur