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?
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.
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.
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.
Explicit (full) specializationAllows customizing the template code for a given set of template arguments.
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) { // ... }
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) { // ... }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With