How has += operator been implemented in c++?

早过忘川 提交于 2020-12-12 05:36:33

问题


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 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.

(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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!