17

I'm new to C++. The book I read tells me that if the plus (+) operator has been overloaded for some class object, say, the string class, to make this problem more concrete.

#include<iostream>
#include<string>
using namespace std;

int main()
{
    string s1("abc");
    string s2("def");

    string s3("def");

    cout<<(s1+s2=s3)<<endl;

    int x=1;
    int y=2
    int z=3;
    cout<<(x+y=z)<<endl;

    return 0;
}

As you may expect, the first cout statement is correct while the second is wrong. The compiler complaints x+y is not a modifiable lvalue. My question is why the + operator returns a modifiable lvalue for string objects but not for int?

Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
James Fan
  • 199
  • 6

2 Answers2

20

It does not return a modifiable lvalue for string. It returns a temporary object, and s1+s2 and x+y are both rvalues.

However, objects of class type may have overloaded operator=, which string does. You are allowed to call member functions on rvalues.

The difference between the two cases is in = (not +)

M.M
  • 138,810
  • 21
  • 208
  • 365
  • 1
    Note that this is a problem which is being [worked on](http://stackoverflow.com/a/21052529/15416). You can prevent calling `operator=` on rvaliues of your own classes. Problem is, there's existing code that would break if the C++ standard would be changed to forbid assignment to `std::string` rvalues. – MSalters Aug 14 '15 at 14:50
  • @MSalters Yeah, [a wise man](http://stackoverflow.com/questions/28598468/does-it-improve-safety-to-mark-assignment-operators-as-lvalue-only) once inquired the same..:) – M.M Aug 15 '15 at 02:38
14

For std::string, s1 + s2 = s3 is in fact:

(operator+(s1, s2)).operator =(s3)

s1 + s2 returns a rvalue

Member methods can be applied to temporary also.
Since C++11, we have the lvalue/rvalue qualifier for method,
so you may forbid o1 + o2 = o3 for your custom type with:

struct Object
{
    Object& operator =(const Object& rhs) & ; // Note the & here
};

so Object::operator = can only be applied to lvalue.

Jarod42
  • 203,559
  • 14
  • 181
  • 302