Reputation: 21
So I have this class template with a single attribute value
of type T
where I try to overload the +
operator, s.t. adding two objects of this class results in another object of this class where the value
is the sum of the value
s of the two. Here's the code:
template<typename T>
class Number
{
public:
//constructors
Number(T value)
: value(value) {}
//attributes
const T value;
//operators
//addition +
template<typename U>
auto operator+(Number<U> other)
{
auto val = this->value + other.value;
Number output(val); //instantiating object of class Number, using constructor
std::cout << "output value: "<<output.value << std::endl;
std::cout << "auto val: "<< val << std::endl;
return output;
}
};
int main()
{
Number<int> x(2);
Number<float> y(2.5);
Number z=x+y;
std::cout << "x = " << x.value << std::endl;
std::cout << "y = " << y.value << std::endl;
std::cout << "x+y = " << z.value << std::endl;
return 0;
}
. The output is:
output value:4
auto val: 4.5
x = 2
y = 2.5
x+y = 4
.
Obviously there occurs and undesired type conversion, from float
to int
and I am trying to find out how to avoid this without resorting to specialization. Explicit declaration of the operator output type does not compile. I understand that here the failure lies in that the auto
type output becomes the type Number<T>
, which in this case is Number<int>
but does it have to be int
even when a new object is instantiated within the operator definition scope { }
?
I'd appreciate some help in this simple exercise, thank you in advance!
Upvotes: 2
Views: 87
Reputation: 82461
As @NathanPierson mentioned:
Number
refers to Number<T>
inside the operator. You unfortunately cannot use template argument deduction here.
The return type can be determined based on the type of the additon though. You could use a trailing return type to specify the return type. This assumes you don't need to use the result before returning from the function.
class Number
{
public:
...
template<typename U>
auto operator+(Number<U> other) -> Number<decltype(other.value + value)>
{
return {value + other.value};
}
};
.
You could also implement the operator in namespace scope:
template<class T, class U>
auto operator+(Number<T> const& s1, Number<U> const& s2)
{
auto val = s1.value + s2.value;
Number result(val);
return result;
}
Upvotes: 1