Hi there,
I just started with programming in C++ with a video tutorial. Everything was going alright until i got to a weird compiler error while overloading the operator+ for a class I created myself (See code below).
Since the tutorial was done in .NET and I am working with Xcode I tried the same code (copy pasted it) in .NET myself and got no compiler errors, every thing seemed fine.

I think this is pretty strange since it's just basic C++ without having used any platform dependent code. Has anybody got any idea what it can be or how it can be solved?

Here is the code (the error and location are after the code):

Code:
```#include <iostream>

using namespace std;

//------------------------------
//Point class begin
//------------------------------
class Point
{
public:
Point(float f_x = 1.0, float f_y = 1.0, float f_z = 1.0);
~Point();

float getX();
float getY();
float getZ();

void setX(float X);
void setY(float Y);
void setZ(float Z);

Point operator =(Point &p);
Point operator +(Point &p);

private:
float x, y, z;

protected:

};

Point::Point(float f_x, float f_y, float f_z)
{
x = f_x;
y = f_y;
z = f_z;
}

Point::~Point()
{
}

float Point::getX()
{
return x;
}

float Point::getY()
{
return y;
}

float Point::getZ()
{
return z;
}

void Point::setX(float X)
{
x = X;
}

void Point::setY(float Y)
{
y = Y;
}

void Point::setZ(float Z)
{
z = Z;
}

Point Point::operator =(Point &p)
{
setX(p.getX());
setY(p.getY());
setZ(p.getZ());

return *this;
}

Point Point::operator +(Point &p)
{
Point outP;
outP.setX(getX() + p.getX());
outP.setY(getY() + p.getY());
outP.setZ(getZ() + p.getZ());

return outP;
}

//---------------------------
//Point class end
//---------------------------

int main (int argc, char * const argv[])
{
Point p1(4, 2, 1);
Point p2(6, 3, 8);

Point p3;
p3 = p2 + p1;

return 0;
}```
When I compile this in Xcode I get the follow error on the following line in main:
Code:
`p3 = p2 + p1;`
error: no match for 'operator=' in 'p3 = Point::operator+(Point&)(((Point&)(& p1)))'

as I said, if I copy paste this code to .NET (Visual C++ 2008 Express edition) it works perfectly with no errors;

I also found out that if I write the following statement:
Code:
`Point p3 = p2 + p1;`
the compiler doesn't give an error in Xcode and it can be run correctly with normal behaviour.

Very strange if I may say so, but maybe it's because I'm new to C++ and I missed a detail.

2. In p3=p2+p1, you're using both the overloaded operator + and the overloaded operator =. The operator + returns a Point, but apparently not a modifiable lvalue that can be referenced (the operator = requires a Point&). The initializer doesn't use your overloaded operator =, but the default copy constructor.

3. Isn't it then strange that the code does work in .Net but doesn't in Xcode, I know they both have different compiler so there will be differences but isn't this just basic C++ that should work on both platforms (mac or windows).

Would anybody know a solution how I could make the following statement work:

Code:
```Point p3;
p3 = p2 + p1;```

4. operator+ returns a temporary instance, which cannot be passed by non-const reference to operator=.

It can be passed when a const reference is expected.

So, to fix this class make it const-correct. If a method doesn't modify the instance's members, declare it const. When passing an object to a function by reference and the function is not going to modify the object (calls only const methods), pass it as a const reference.

Code:
```class Point
{
public:
Point(float f_x = 1.0, float f_y = 1.0, float f_z = 1.0);
~Point();

float getX() const;
float getY() const;
float getZ() const;

void setX(float X);
void setY(float Y);
void setZ(float Z);

Point& operator =(const Point &p);
Point operator +(const Point &p) const;

private:
float x, y, z;

protected:

};```
Actually, since your operator= does nothing but a memberwise assignment, you don't need to implement it yourself. The compiler would generate the assignment operator automatically and it would do exactly the same thing.
Neither do you need to write the destructor, if you are not going to do anything in it.

5. Thanks for the reply, if I add the const to all the places you say it still comes up with the error. So that doesn't seem to do the trick.

However if I remove the operator= function the error seems to disappear.
In this case it is useless to overload the operator= function because the behavior is just normal, but what if you would want to swap x and y for example (I know it would be stupid in and = operator but just for the sake of it) or wanted to add more complex behavior and the operator= would be necessary. But because I was doing the tutorial they where showing the possibilities of overloading (that's why the destructor is there to).

And I still think it's weird that it works in .NET but not in Xcode, anybody got any ideas about that?

The compiler also still gives me a waring with the following note (at the line where I implement my operator=):

note: candidates are: Point Point::operator=(Point&)

but this seems to be exactly what I've implemented

6. Originally Posted by Sjiep

The compiler also still gives me a waring with the following note (at the line where I implement my operator=):

note: candidates are: Point Point:perator=(Point&)

but this seems to be exactly what I've implemented
Of course it is: that's what it's telling you. "I know how to do operator= if you give me a Point&, but you didn't give me a Point&, so I'm stuck."

7. Have operator= return a reference so you can chain assignments, i.e.

Point & operator=(const Point &);

8. Originally Posted by medievalelks
Point & operator=(const Point &);
This seems to do the trick, even tho it still gives the following warning:

warning: reference to local variable 'outV' returned

It does the trick and runs properly.

Thanks everyone for the (fast) response!!

9. Eh, that's bad. It may work properly now, but returning a reference to a local variable results in undefined behaviour. Typically, operator= returns *this.

Incidentally, I note that anon's example declaration of operator= returns a Point&, so kindly read examples carefully and ask if you are not sure why they are the way they are.

10. Originally Posted by laserlight
Eh, that's bad. It may work properly now, but returning a reference to a local variable results in undefined behaviour. Typically, operator= returns *this.
Typically, operator= returns a *reference* to *this. Otherwise, you could not do things like this:

std::string w, x, y, z;

z = y = w = x = "Hello";

This mimics the behavior of built-in types.

11. Typically, operator= returns a *reference* to *this.
I felt that was obvious given the context, but good clarification nonetheless.

Otherwise, you could not do things like this:
You could also do operator chaining if operator= returns by value, but it would (semantically) result in unnecessary copies.

12. Originally Posted by Sjiep
This seems to do the trick, even tho it still gives the following warning:

warning: reference to local variable 'outV' returned

It does the trick and runs properly.

Thanks everyone for the (fast) response!!
Your operator+ has an outP and has to return by value because it creates a whole new object (and operator+ should not modify either the left hand nor the right hand value).

Operator= however should modify *this (the left hand value) and not return any local objects.

You may need to post new code if you still have this problem.

13. Originally Posted by laserlight
You could also do operator chaining if operator= returns by value, but it would (semantically) result in unnecessary copies.
Oops. I recently argued against someone writing a "void operator=()" at work, and still had that on my brain.

14. Well I changed the code to Anons first post but the same error still pops up:
Code:
```#include <iostream>

using namespace std;

//------------------------------
//Point class begin
//------------------------------
class Point
{
public:
Point(float f_x = 1.0, float f_y = 1.0, float f_z = 1.0);
~Point();

float getX() const;
float getY() const;
float getZ() const;

void setX(float X);
void setY(float Y);
void setZ(float Z);

Point& operator =(Point &p);
Point operator +(Point &p) const;

private:
float x, y, z;

protected:

};

Point::Point(float f_x, float f_y, float f_z)
{
x = f_x;
y = f_y;
z = f_z;
}

Point::~Point()
{
}

float Point::getX() const
{
return x;
}

float Point::getY() const
{
return y;
}

float Point::getZ() const
{
return z;
}

void Point::setX(float X)
{
x = X;
}

void Point::setY(float Y)
{
y = Y;
}

void Point::setZ(float Z)
{
z = Z;
}

Point& Point::operator =(Point &p)
{
setX(p.getX());
setY(p.getY());
setZ(p.getZ());

return *this;
}

Point Point::operator +(Point &p) const
{
Point outP;
outP.setX(getX() + p.getX());
outP.setY(getY() + p.getY());
outP.setZ(getZ() + p.getZ());

return outP;
}

//---------------------------
//Point class end
//---------------------------

int main (int argc, char * const argv[])
{
Point p1(4, 2, 1);
Point p2(6, 3, 8);

Point p3;
p3 = p2 + p1;

return 0;
}```
The error just changed slightly because of the const:

error: no match for 'operator=' in 'p3 = Point:perator+(Point&) const(((Point&)(& p1)))'

Then I had a closer look at the warning it told me and come up with the following that also seems to work with no errors or warnings:

Code:
```class Point
{
public:
Point(float f_x = 1.0, float f_y = 1.0, float f_z = 1.0);
~Point();

float getX();
float getY();
float getZ();

void setX(float X);
void setY(float Y);
void setZ(float Z);

Point operator =(Point *p);
Point operator +(Point &p);

private:
float x, y, z;

protected:

};```
I'm only wondering is this correct C++? It looks alright to me.

And can anybody still tell me why my original code doesn't work in Xcode but will work in .NET?

15. Code:
`Point& Point::operator =(Point &p)`
should be:
Code:
`Point& Point::operator =(const Point &p)`
because you aren't (and shouldn't be) modifying p.
After that, it compiles fine in Comeau C++ compiler.

Originally Posted by Sjiep
And can anybody still tell me why my original code doesn't work in Xcode but will work in .NET?
I have no idea? Maybe one of them has a bug, or maybe one has an extension to try to make it more helpful?