我想对几种整数类型(16,32,64位)和浮点类型(float,double,long double)执行类似但不完全相同的计算。大多数代码都是相同的,但是对于整数和浮点数,某些部分需要以不同的方式完成。例如,比较int可以用a == b来完成,而比较浮点数应该用abs(a-b)来完成
这样做的一种方法是将int和flo之间不同的代码部分隔离成小函数,并为每种类型专门化模板。但是,我宁愿不为每个整数类型复制粘贴相同的代码,也不为每个浮点类型复制粘贴相同的代码。因此问题是:是否可以同时为多种类型专门化模板功能?如果它是合法的,那么在语义上类似于以下内容:
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;
}
答案 0 :(得分:15)
使用C ++ 11可以使用type traits。请参阅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;
}
答案 1 :(得分:3)
是的,您可以将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();
}
答案 2 :(得分:2)
您可以专注于<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);
};