简体   繁体   English

区分模板中的整数和浮点类型

[英]Distinguishing integer from floating point types in a template

I'd like to perform similar, but not identical computations for several integer types (16, 32, 64 bits) and floating point types (float, double, long double). 我想对几种整数类型(16,32,64位)和浮点类型(float,double,long double)执行类似但不相同的计算。 Most of the code is identical, but some portions need to be done differently for ints and floats. 大多数代码都是相同的,但是对于整数和浮点数,某些部分需要以不同的方式完成。 For example, comparing ints can be done with a==b, while comparing floats should be done with abs(ab) 例如,比较int可以用a == b来完成,而比较浮点数应该用abs(ab)来完成

One way to do that would be to isolate the parts of code that are different between ints and floats into small functions and specialize template for each type. 一种方法是将整数和浮点之间不同的代码部分隔离成小函数,并为每种类型专门化模板。 However, I'd rather not to copy-paste identical code for each of the integer types and another code for each of the float types. 但是,我宁愿不为每个整数类型复制粘贴相同的代码,也不为每个浮点类型复制粘贴相同的代码。 Thus the question: is it possible to specialize template function for multiple types at once? 因此问题是:是否可以同时为多种类型专门化模板功能? Something semantically similar to the following if it was legal: 如果它是合法的,在语义上类似于以下内容:

template<>
bool isEqual< short OR long OR long long >( T a, T b ) { 
    return a == b;
}

template<>
bool isEqual< float OR double OR long double >( T a, T b ) { 
    return abs( a - b ) < epsilon;
}

With C++11 it is possible to use type traits . 使用C ++ 11,可以使用类型特征 See std::enable_if documentation In your case, it might look like this: 请参阅std::enable_if文档在您的情况下,它可能如下所示:

Function parameter specialization: 功能参数专业化:

template<class T>
bool isEqual(T a, T b, typename std::enable_if<std::is_integral<T>::value >::type* = 0) 
{
    return a == b;
}

template<class T>
bool isEqual(T a, T b, typename std::enable_if<std::is_floating_point<T>::value >::type* = 0) 
{
    return abs( a - b ) < epsilon;
}

Return type specialization: 返回类型专业化:

template<class T>
typename std::enable_if<std::is_integral<T>::value, bool >::type isEqual(T a, T b)

{
    return a == b;
}

template<class T>
typename std::enable_if<std::is_floating_point<T>::value, bool >::type isEqual(T a, T b)
{
    return abs( a - b ) < epsilon;
}

Yes, you can use SFINAE in combination with the metafunctions from <type_traits> 是的,您可以将SFINAE与<type_traits>的元函数结合使用

#include<type_traits>

template<class IntegralType>
typename std::enable_if<
    std::is_integral<IntegralType>::value,
    bool>::type

isEqual(IntegralType a,IntegralType b)
{
    return a == b;
}

template<class FloatingType>
typename std::enable_if<
    std::is_floating_point<FloatingType>::value,
    bool>::type

isEqual(FloatingType a,FloatingType b)
{
    return fabs(a-b) <  std::numeric_limits<FloatingType>::epsilon();
}

You can specialize on <type_traits> 您可以专注于<type_traits>

Then you can group functions based on categories 然后,您可以根据类别对功能进行分组

template<typename T, bool INTEGRAL> class isEqualbyType;

template<typename T>
class isEqualbyType<T, true>
{
public:
    static bool cmp( T a, T b ) { 
        return a == b; }
};

template<typename T>
class isEqualbyType<T, false>
{
public:

    static bool cmp( T a, T b ) {
        static const double epsilon=1e-50;
        return abs( a - b ) < epsilon; }
};

template<typename T>
bool isEqual( T a, T b )
{
   return isEqualbyType<T, std::is_integral<T>::value>::cmp(a,b);
};

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

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