10

I want to add 2 objects, by overloading the + operator, but my compiler says there's no matching function to call to point::point(int, int). Can somebody please help me with this code, and explain the error ? thank you

#include <iostream>

using namespace std;

class point{
int x,y;
public:
  point operator+ (point & first, point & second)
    {
        return point (first.x + second.x,first.y + second.y);
    }
};

int main()
{
    point lf (1,3)
    point ls (4,5)
    point el = lf + ls;
    return 0;
}
user4581301
  • 33,082
  • 7
  • 33
  • 54
Snowshoot
  • 173
  • 1
  • 4
  • 16
  • As a member function it takes only one argument. – Cheers and hth. - Alf Sep 17 '18 at 23:01
  • Tip: as a non-member function it will support a first argument that isn't directly `point` but provides implicit conversion to `point`. That's not possible with the member function. And so the preferred way to define infix `+` is as a non-member function. One to get that is just to add `friend` in front of the definition you already have. – Cheers and hth. - Alf Sep 17 '18 at 23:03
  • If you declare the operator+ as you have done, it needs to be outside the class definition – Alberto Miola Sep 17 '18 at 23:03
  • 2
    Much wisdom on this and other similar topics can be found at [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) – user4581301 Sep 17 '18 at 23:05
  • It's OK that that the arguments are references, but then they should be references to `const point`, to support rvalue expressions and `const point` actual arguments. – Cheers and hth. - Alf Sep 17 '18 at 23:06
  • If you need a 3-operand summation, you will need non-overloaded method of it or a function. double sum(double a, double b, double c) { return a+b+c; } – huseyin tugrul buyukisik Sep 17 '18 at 23:11

3 Answers3

13

You can just change your code like this,

#include <iostream>

using namespace std;

class point {
    int x, y;
public:
    point(int i, int j)
    {
        x = i;
        y = j;
    }

    point operator+ (const point & first) const
    {
        return point(x + first.x, y + first.y);
    }

};

int main()
{
    point lf(1, 3);
    point ls(4, 5);
    point el = lf + ls;

    return 0;
}

Hope this helps...

4
class point{
  int x,y;
public:
  point& operator+=(point const& rhs)& {
    x+=rhs.x;
    y+=rhs.y;
    return *this;
  }
  friend point operator+(point lhs, point const& rhs){
    lhs+=rhs;
    return lhs;
  }
};

There are a pile of little tricks above that make following this pattern a good "no brainer".

  1. You get both += and + with the "proper" semantics.
  2. If you chain +s together, you get elision of the left hand side operation. (ie, a+b+c becomes (a+b)+c, the return value of a+b is elided into the _+c call). If your objects have movable state, the proper moves happen for no design cost.
  3. a+b works if either a or b is a point, and the other has an implicit-conversion-to-point. Member operator+ does not do this if a is not a point; this is pointless asymmetry.
  4. a+=b is often more efficient to implement than a=a+b. When you implement += here, you get an efficient + as well. And your += is in turn defined in terms of member variable +=s.
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
3

The error with gdb I get is

main.cpp:8:49: error: ‘point point::operator+(point&, point&)’ must take either zero or one argument

This is because the the object that you plan to perform the operation on is this (the left hand side) and then the right hand side is the argument. If you wish to use the format that you've taken, then you can put the declaration outside the class - ie

struct point
{
  // note made into a struct to ensure that the below operator can access the variables. 
  // alternatively one could make the function a friend if that's your preference
  int x,y;
};

point operator+ (const point & first, const point & second) {
  // note these {} are c++11 onwards.  if you don't use c++11 then
  // feel free to provide your own constructor.
  return point {first.x + second.x,first.y + second.y};
}
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
UKMonkey
  • 6,941
  • 3
  • 21
  • 30
  • "then you must put the declaration outside the class". No, I generally prefer to define such as `friend` functions inside the class. But it depends, as always. – Cheers and hth. - Alf Sep 17 '18 at 23:07
  • With your structure the compiler throws this "error: no matching function for call to 'point::point()'|" at me so it still doesn't really work – Snowshoot Sep 17 '18 at 23:08