简体   繁体   English

如何对多种类型进行一次显式专业化?

[英]How to do one explicit specialization for multiple types?

Considering a template function like below how is it possible to do explicitly specialize one version of function for multiple types: 考虑下面的模板函数,如何为多种类型明确地专门化一个版本的函数:

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

The intention is to have one specialization instead of multiple following ones because //something is the same: 目的是有一个专门化而不是多个跟随,因为//有些东西是相同的:

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

any method to achieve one specialization? 任何方法实现一个专业化?

You can't make template function specialization. 您无法进行模板功能专业化。 But you could delegate the implementation in a helper class, that can be used from your function. 但是您可以在helper类中委托实现,可以从您的函数中使用。 Some skeleton code: 一些骨架代码:

Implement a template class and specialize 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>()();
}

Where IsArithmetic is a class that provides the information about type T (selector). IsArithmetic是一个提供有关类型T(选择器)的信息的类。 You can find such type info in boost libraries, for example. 例如,您可以在boost库中找到此类型信息。

You could just have a kind of doSomethingImpl function. 你可以有一种doSomethingImpl函数。

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

It's also possible to specialize more generically, using SFINAE and std::is_numeric<T> , for example. 例如,使用SFINAE和std::is_numeric<T>也可以更通用地进行专业化。

using c++ 2011 (option -std=c++11), this works well: 使用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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM