operator +=, -=, *=, /=

If we have a class with custom +, -, *, / and = operators is there any particular reason why the compiler can't automatically generate operators +=, -=, *=, /= like this:
1
2
3
4
5
6
7
class foo {
   // etc
public:
   // etc
   foo operator+=(foo bar) { *this = *this + bar; return *this; }
   // etc
};

since most of the time, I should imagine this is how we would be using these operators.
The compiler probably could, but it doesn't.

Besides it should probably be the other way around (generate +, -, etc from +=, -=, etc)


If it's really such a bother for you, you can do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
using namespace std;

class Foo
{
public:
    Foo& operator += (const Foo& foo)
    {
        cout << "adding";
        return *this;
    }
};

// if you template it, the template will work for any type 'T'
template <typename T>
inline T operator + (const T& l, const T& r)
{
    T v(l);
    return v += r;
}

int main()
{
    Foo a, b;
    Foo c;

    c = a + b; // invokes the template +, which calls Foo::operator +=

    cin.get();
}
Line 5 should have foo& and const foo&..
Also, It may often be better to express + by += than vice versa to save one copying.

As for the actual question, there are many many things compilers could do, but don't...
there are many many things compilers could do, but don't...

I know, but this one seemed particularly simple, so I wondered if there was a particular reason for it not being possible.

should have foo& and const foo&

Oh yeah... This is not the case for operator+, etc. though, right?

If it's really such a bother for you, you can do this:

Thanks for the code suggestion. In fact it was more curiosity than it being a bother to type it by hand.

Besides it should probably be the other way around
save one copying.

Sorry if I'm being slow, but where is the additional copy in the second case?
1
2
T v(l); // copy
return v+= r;

has one copy. And
1
2
*this = *this + bar; // copy
return *this;

has one copy.
Last edited on
You should take a look at Boost.Operators, which exists precisely so you don't have to define all of these yourself.
http://www.boost.org/doc/libs/1_45_0/libs/utility/operators.htm
Last edited on
save one copying

+ through += :
1
2
3
4
5
6
7
8
9
10
11
struct MyInt{
   int x;
   MyInt& operator += (const MyInt& a) {
      x += a.x;//no copying
      return *this;
   }
   MyInt operator + (const MyInt& a) {
      MyInt b = *this;//one copy
      return b+=a;//one copy
   }
}


+= though + :
1
2
3
4
5
6
7
8
9
10
11
struct MyInt{
   int x;
   MyInt operator + (const MyInt& a) {
      MyInt b;//not really a copy.. but does use memory and call a constructor
      b.x = x+a.x;
      return b;//a copy
   }
   MyInt& operator += (const MyInt& a) {
      return *this = *this + bar;//copy and a copy inside operator + 
   }
}


Though now that I think about it, I'm not sure whether I make sense.. Also, I really have no idea how smart compilers are.
@Athar I thought it was the kind of thing Boost would have...

@hamsterman Well the second one seems a little better, though as you say, MyInt b has the potential to require about half the operations used by a copy if the constructor sets all the member variables to defaults.

Presumably, in the right circumstances, the copies caused by returns in both cases may be removed by RVO.
Topic archived. No new replies allowed.