I have a templated math function which takes two values, does some math to them, and returns a value of the same type.
template <typename T>
T math_function(T a, T b) {
LongT x = MATH_OP1(a,b);
return MATH_OP2(x,a);
}
I want to store intermediate values (in x) in a type which is basically the long version of T (above, called LongT). So, if T is float, I want x to be a double; and if T is an int, I want x to be a long int.
Is there some way to accomplish this? I tried enable_if
, but it seems that I would really need an enable_if_else
.
I'd prefer to have the compiler figure out what to use for LongT on its own. I'd rather not have to specify it when I call the function.
You can define a type mapping that will yield the needed type:
template <typename T> struct long_type;
template <> struct long_type<int> {
typedef long type;
};
template <> struct long_type<float> {
typedef double type;
};
And then use that metafunction:
template <typename T>
T math_function(T a, T b) {
typename long_type<T>::type x = MATH_OP1(a,b);
return static_cast<T>(MATH_OP2(x,a));
}
With this particular implementation, your template will fail to compile for any type other than the ones for which you have provided the long_type
trait. You might want to provide a generic version that will just map to the itself, so that if the input is long long int
that is what is used (assuming no larger type in your architecture).
Assuming you don't need to handle T=long
for example, just create traits for int
and float
:
template <typename T>
struct LongT;
template <>
struct LongT<int>
{
typedef long value_type;
};
template <>
struct LongT<float>
{
typedef double value_type;
};
template <typename T>
T math_function(T a, T b) {
typename LongT<T>::value_type x = MATH_OP1(a,b);
return MATH_OP2(x,a);
}
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