In the expression:
D=A+B+C
A and B are lvalues, so calling A+B calls Vector::operator(const Vector&)
This returns an rvalue, let it call it tmp , so the next subexpression is tmp+C
C also an lvalue, so it calls Vector::operator(const Vector&) again. This returns a different r value, lets call it tmp2
The final subexpression is D=tmp2 , but your type does not have a redirection operator, so the implicit copy assignment operator is used.
i.e. you never call operator+ with an rvalue on the right side, and the only expression that has an rvalue argument is an assignment that you did not define for rvalues.
It would be better to define overloaded operators that are not members:
Vector operator+(const Vector&, const Vector&); Vector operator+(Vector&&, const Vector&); Vector operator+(const Vector&, Vector&&); Vector operator+(Vector&&, Vector&&);
This will work for any combination of r and lvalues. (Normally, operator+ should usually be non-member.)
Edit: the alternative sentence below does not work, in some cases this leads to ambiguity.
Another alternative, if your compiler supports it (I think that only clang does), should have kept your existing Vector::operator+(Vector&&) , but replaced your Vector::operator+(const Vector&) with two overloads that differ in ref-qualifier :
Vector Vector::operator+(const Vector& v) const& { Vector tmp(*this); tmp += v; return tmp; } Vector Vector::operator+(const Vector& v)&& { *this += v; return std::move(*this); }
Reuses *this when it is known as rvalue, i.e. uses move semantics when the left side of addition is an rvalue, compared to the source code, which can only use move semantics when the right side is an rvalue. (NB in ββthe above code, it is assumed that you defined the operator+= member as suggested in David Rodriguez's answer)