Consider following code snippet:
template <typename U>
struct Un {
Un (int p) : n {p} {}
U operator+ (U v) const {
return U {n + v.n};
}
int n {};
};
struct R : Un<R> {
using Un::Un;
};
struct D : Un<D> {
using Un::Un;
D (R v) : Un {v.n} {}
operator R () const {
return n;
}
};
and usage is as follows:
template <typename T>
void what_type (T t) {
std::cout << "type R = " << std::is_same<T, R>::value << std::endl;
std::cout << "type D = " << std::is_same<T, D>::value << std::endl;
}
R r {10};
D d {10};
what_type (r+d);
what_type (d+r);
output is:
type R = 1
type D = 0
type R = 0
type D = 1
which means that if in the arithmetic expression R
type occurs as the first one, the whole expression is of type R
and if D
type occurs firstly then the expression is of type D
.
So, my understanding is like this:
in r+d
firstly we create object of R
type, then object of D
type and because D
has operator R()
implemented, D
object is converted to R
, which gives us in fact r+r
.
in d+r
firstly we create object of D
type, then object of R
type and because D
has constructor which takes R
object it creates D
object from previously created r
, which gives us in fact d+d
.
Is my understanding correct? Or are there other rules for that kind of situation?
Your understanding is flawed. You defined binary operator+
as a member function. That means that the left hand of the assignment is set in stone. For D
and R
it's D
and R
, respectively.
d+r
is essentially the same thing as d.operator+(r)
, which for Un<D>
returns D
. It's the same thing in reverse for r+d
.
In neither expression you "create" the left operand. The right one is indeed converted in both.
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