Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Return type depending on the order in arithmetic operation. Is it correct?

Tags:

c++

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?

like image 467
Artur Pyszczuk Avatar asked Mar 11 '23 19:03

Artur Pyszczuk


1 Answers

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.

like image 57
krzaq Avatar answered Mar 16 '23 00:03

krzaq