簡體   English   中英

區分模板中的整數和浮點類型

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

我想對幾種整數類型(16,32,64位)和浮點類型(float,double,long double)執行類似但不相同的計算。 大多數代碼都是相同的,但是對於整數和浮點數,某些部分需要以不同的方式完成。 例如,比較int可以用a == b來完成,而比較浮點數應該用abs(ab)來完成

一種方法是將整數和浮點之間不同的代碼部分隔離成小函數,並為每種類型專門化模板。 但是,我寧願不為每個整數類型復制粘貼相同的代碼,也不為每個浮點類型復制粘貼相同的代碼。 因此問題是:是否可以同時為多種類型專門化模板功能? 如果它是合法的,在語義上類似於以下內容:

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;
}

使用C ++ 11,可以使用類型特征 請參閱std::enable_if文檔在您的情況下,它可能如下所示:

功能參數專業化:

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;
}

返回類型專業化:

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;
}

是的,您可以將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();
}

您可以專注於<type_traits>

然后,您可以根據類別對功能進行分組

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