How to make one explicit specialization for several types?

Given the function of the template, as shown below, how can we explicitly single out one version of the function for several types:

template <typename T>
void doSomething(){
 //whatever
}

The goal is to have one specialization instead of several of the following, because // something is the same:

void doSomething<int>(){
 //something
}
void doSomething<float>(){
 //something
}
void doSomething<double>(){
 //something
}

any method to achieve one specialization?

+3
source share
3 answers

You cannot create a specialized function for a template. But you can delegate the implementation in a helper class that can be used from your function. Some skeletal codes:

Deploy the template class and select it:

template< typename T, bool isArithmetic>
struct Something { void operator()() { ... } };

template< typename T, true>
struct Something { void operator()() { ... do something specialized for arithmetic types; } }

Then use it in the template function:

template< typename T>
void myFunction()
{
   Something<T, IsArithmetic<T>::value>()();
}

IsArithmetic - , T (). , ​​ .

+4

- doSomethingImpl.

template<typename T> doSomethingImpl() {
    // whatever
}
template<typename T> doSomething() {
    // something else
}
template<> doSomething<float>() {
    doSomethingImpl<float>();
}
template<> doSomething<int>() {
    doSomethingImpl<int>();
}

, SFINAE std::is_numeric<T>, .

+1

using C ++ 2011 (option -std = C ++ 11), this works well:

#include <iostream>

template <typename T>
struct unsignedObject
{
    unsignedObject() {
        std::cout << "instanciate a unsignedObject\n";
    }
};

struct signedObject
{
    signedObject() {
        std::cout << "instanciate a signedObject\n";
    }
};

template <typename T>
struct objectImpl
{
    typedef unsignedObject<T> impl; // optional default implementation (the line can be removed)
};

template <> struct objectImpl<unsigned char>  { typedef unsignedObject<unsigned char>  impl; };
template <> struct objectImpl<unsigned int>   { typedef unsignedObject<unsigned int>   impl; };
template <> struct objectImpl<unsigned short> { typedef unsignedObject<unsigned short> impl; };
template <> struct objectImpl<double>         { typedef signedObject   impl; };
template <> struct objectImpl<int>            { typedef signedObject   impl; };
template <> struct objectImpl<short>          { typedef signedObject   impl; };
template <> struct objectImpl<char>           { typedef signedObject   impl; };

template <typename T>
using object = typename objectImpl<T>::impl;

int main(void)
{
    object<int> x;    // x is a signedObject.
    object<double> y; // y is a signedObject.
    object<unsigned short> z; // z is a unsignedObject.
    return 0;
}
+1
source

Source: https://habr.com/ru/post/1776949/


All Articles