If I have a generic struct/class:
template<typename T>
struct Container
{
T value;
Container(const Value& value) : value(value) { }
};
And I want to perform an operation on two of them:
template<typename T, typename U>
Container<T> operator+(const Container<T>& lhs, const Container<U>& rhs)
{
return Container<T>(lhs.value + rhs.value);
}
The problem is that if lhs
is of the type Container<int>
and rhs
is of the type Container<float>
, then I'll get a Container<int>
back. But if I were to do auto result = 2 + 2.0f
, then result
would of of type float
. So the behavior is inconsistent between builtin types and custom types.
So how would I take the operator+
overload and make it return Container<float>
, much like how C++ handles arithmetic promotion with builtin types?
As far as you use one of the two types of the template, you risk to induce a cast on the result of the sum. As an example, if you accidentally choose int
as your target type, even though the sum results in a float
, it will be cast down to the chosen type.
Anyway, starting with C++11, you con rely on the decltype
specifier as in the example above (or at least, you can do that if Container::T
and Container::U
are a types for which the +
operator is defined).
I used also the auto
specifier as return value for the operator+
, for it is at our disposal starting from C++14 and it's really useful indeed.
It follows the working example above mentioned:
#include <iostream>
#include <vector>
template<typename T>
struct Container
{
T value;
Container(const T& value) : value(value) { }
};
template<typename T, typename U>
auto operator+(const Container<T>& lhs, const Container<U>& rhs)
{
return Container<decltype(lhs.value+rhs.value)>{lhs.value + rhs.value};
}
int main()
{
Container<int> c1{1};
Container<float> c2{0.5};
std::cout << (c1+c2).value << std::endl;
}
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