Как сделать одну явную специализацию для нескольких типов? - PullRequest
3 голосов
/ 25 ноября 2010

Рассматривая шаблонную функцию, как показано ниже, как можно явно специализировать одну версию функции для нескольких типов:

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

Намерение состоит в том, чтобы иметь одну специализацию вместо нескольких следующих, потому что // что-то одно и то же:

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

любой метод для достижения одной специализации?

Ответы [ 3 ]

4 голосов
/ 25 ноября 2010

Вы не можете сделать специализацию функции шаблона.Но вы можете делегировать реализацию в вспомогательный класс, который можно использовать из вашей функции.Немного скелетного кода:

Реализация шаблона шаблона и его специализация:

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

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

Затем используйте его в функции шаблона:

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

Где IsArithmetic - это класспредоставляет информацию о типе T (селектор).Вы можете найти такую ​​информацию о типах в библиотеках boost, например.

1 голос
/ 24 октября 2017

с использованием c ++ 2011 (опция -std = c ++ 11), это хорошо работает:

#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 голос
/ 25 ноября 2010

Вы можете просто использовать функцию 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>.

...