The most popular operator which should return reference is operator=
class Alpha
{
int x;
int y;
std::string z;
public:
void print()
{ cout << "x " << x << " y " << y << " " << z << '\n'; }
Alpha(int xx=0, int yy=0, std::string zz=""): x(xx), y(yy), z(zz) {}
Alpha operator=(Alpha& another)
{
x = another.x;
y = another.y;
z = another.z;
return *this;
}
};
int main()
{
Alpha a(3,4,"abc"),b,c;
b=c=a;
return 0;
}
Clang says this:
clang++-3.6 new.cxx -o new new.cxx:70:3: error: no viable overloaded '=' b=c=a; ~^~~~ new.cxx:34:8: note: candidate function not viable: expects an l-value for 1st argument Alpha operator=(Alpha& another) ^ 1 error generated.
gcc this:
new.cxx:34:8: note: no known conversion for argument 1 from ‘Alpha’ to ‘Alpha&’
But I can't understand what's the problem in theory. What I think happens:
- Firstly operator= is called for object
c
. It receives objecta
by reference, copies it's values to c and returns anonymous copy of it's self (of objectc
): Copy soncstructor is called. - Then operator= is called for object
b
. It requires rvalue ref, but we have only written lvalue reference, so the error occurs.
I have added rval operator= and copy constructor, which receives lvalue reference and everything works, now I have no idea why (I should have written rvalue copy constructor which receive const Alpha& s
or Alpha&& s
):
class Alpha
{
int x;
int y;
std::string z;
public:
void print()
{ cout << "x " << x << " y " << y << " " << z << '\n'; }
Alpha(int xx=0, int yy=0, std::string zz=""): x(xx), y(yy), z(zz) {}
//Alpha(Alpha&& s): x(s.x), y(s.y), z(s.z) {}
Alpha(Alpha&& ) = delete;
Alpha(Alpha& s): x(s.x), y(s.y), z(s.z) {}
Alpha operator=(Alpha& another)
{
x = another.x;
y = another.y;
z = another.z;
return *this;
}
Alpha operator=(Alpha&& another)
{
x = another.x;
y = another.y;
z = another.z;
return *this;
}
};