问题
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 += b
doesn'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