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). 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(a-b)
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. See std::enable_if
documentation
In your case, it might look like this:
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>
#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();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With