Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++11: Template Function Specialization for Integer Types

Suppose I have a template function:

template<typename T> void f(T t) {     ... } 

and I want to write a specialization for all primitive integer types. What is the best way to do this?

What I mean is:

template<typename I where is_integral<I>::value is true> void f(I i) {     ... } 

and the compiler selects the second version for integer types, and the first version for everything else?

like image 643
Andrew Tomazos Avatar asked Aug 22 '12 12:08

Andrew Tomazos


People also ask

What is the specialty of a template function give example?

Template in C++is a feature. We write code once and use it for any data type including user defined data types. For example, sort() can be written and used to sort any data type items. A class stack can be created that can be used as a stack of any data type.

How will you restrict the template for a specific datatype?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

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. A primary template is the template that is being specialized.

What is explicit template specialization?

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


2 Answers

Use SFINAE

// For all types except integral types: template<typename T> typename std::enable_if<!std::is_integral<T>::value>::type f(T t) {     // ... }  // For integral types only: template<typename T> typename std::enable_if<std::is_integral<T>::value>::type f(T t) {     // ... } 

Note that you will have to include the full std::enable_if return value even for the declaration.

C++17 update:

// For all types except integral types: template<typename T> std::enable_if_t<!std::is_integral_v<T>> f(T t) {     // ... }  // For integral types only: template<typename T> std::enable_if_t<std::is_integral_v<T>> f(T t) {     // ... } 
like image 74
David Avatar answered Oct 07 '22 17:10

David


I would use overload resolution. That spares you from having to use the gross SFINAE hack. Unfortunately there are many areas where you can't avoid it, but this fortunately isn't one of those.

template<typename T> void f(T t) {   f(t, std::is_integral<T>()); }  template<typename T> void f(T t, std::true_type) {    // ... }  template<typename T> void f(T t, std::false_type) {    // ... } 
like image 28
Johannes Schaub - litb Avatar answered Oct 07 '22 17:10

Johannes Schaub - litb