问题
This is a question I've always pondered on and have never found any resource stating the answer to this question. In fact its not only for +=, but also for its siblings i.e. -=, *=, /=, etc. (of course not ==).
Consider the example,
int a = 5;
a += 4;
//this will make 'a' 9
Now consider the equivalent expression:
a = a + 4;
//This also makes 'a' 9
If += were simply a shorthand for a = a + <rhs of +=>
overloading + operator should also implicitly overload +=, unless explicitly overloaded otherwise. But that isn't what happens. That means, a += b doesn't get converted to a = a + b. But then why wasn't it implemented this way? As in, wouldn't it have been easier to simply convert it to a = a + b during compilation instead of implementing it separately as an operator in itself? That would also help in operator overloading, where a += b, where a and b are objects of the same class would not have to be explicitly overloaded, and simply overloading + would have been enough?
EDIT:
My question becomes more clear with this answer
Let me explain my question with an example where one needs to overload the operators:
class A {
int ivar;
public:
A() = default;
A(int par_ivar) : ivar(par_ivar) { }
A(A& a) {
this.ivar = a.ivar;
}
A(A&& a) noexcept {
this.ivar = a.ivar;
}
A operator+(const A& a) const {
A temp_a;
temp_a.ivar = this.ivar + a.ivar;
return temp_a;
}
void operator=(const A& a) {
this.ivar = a.ivar;
}
~A() = default;
};
Now, let's take a look at the result of 2 programs:
prog1:
int main() {
A a1(2);
A a2(3);
a1 = a1 + a2; //a1.ivar = 5
return 0;
}
prog2:
int main() {
A a1(2);
A a2(3);
a1 += a2; //compilation error!!
return 0;
}
Even when both the programs meant to do, nay, do the same thing, one compiles and runs (hoping that my overloads are correct) the other does not even compile!! Had += been simply replaced by appropriate + and =, we would not have felt the need for an explicit overload of +=. Was this intended to be, or is this a feature waiting to be added?
回答1:
Operators are not generated from others (except with/from <=> in C++20):
providing operator < doesn't allow a > b (which is indeed "logically" equivalent to b < a). You have to implement all (even by re-using some).
For classes, a += b is not a shorthand for a = a + b
but for a.operator +=(b) or operator +=(a, b)
In the same way a = a + b is a shorthand for a.operator=(operator +(a, b)) (or its variant)
In practice, it is more efficient to implement operator+ from operator += than the reverse.
Even if a user might expect similar behavior according to their names, they are regular functions.
I already saw a matrix iterator for which ++it increase column index whereas it++ increase row index.
If
+=were simply a shorthand fora = a + <rhs of +=>overloading + operator should also implicitlyoverload +=, unless explicitly overloaded otherwise. But that isn't what happens. That means,a += bdoesn't get converted toa = a + b.
(Possible) rational to not generate might be performance and control:
Vector (for math) or Matrix are good example:
4 possible overloads
Matrix operator+(Matrix&& lhs, Matrix&& rhs) { return std::move(lhs += rhs); }
Matrix operator+(Matrix&& lhs, const Matrix& rhs) { return std::move(lhs += rhs); }
Matrix operator+(const Matrix& lhs, Matrix&& rhs) { return std::move(rhs += lhs); } // + is symmetrical :)
Matrix operator+(const Matrix& lhs, const Matrix& rhs) { auto tmp{lhs}; return tmp += rhs; }
Side effect of the decision allow to give different meanings to operators, as "name operator":
if (42 <in> std::vector{4, 8, 15, 16, 23, 42})
回答2:
Using a = a + b will imply using a copy assignment (as operator = is used). On the other hand, a += b is by default a compound assignment.
According to cppreference,
copy assignment operator replaces the contents of the object a with a copy of the contents of b (b is not modified).
and
compound assignment operators replace the contents of the object a with the result of a binary operation between the previous value of a and the value of b.
Using a = a + b, would therefore cause an unnecessary memory usage, since a has to be copied once before its value is changed.
来源:https://stackoverflow.com/questions/61575287/how-has-operator-been-implemented-in-c