Оператор +, разница между типами классов и встроенными типами?

17

Я новичок в C ++. Книга, которую я прочитал, говорит мне, что если оператор плюс ( + ) был перегружен для некоторого объекта класса, скажем, класса string , чтобы сделать эту проблему более конкретной.

#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;
}

Как вы и ожидаете, первый cout -оператор корректен, а второй неверен. Жалобы компилятора x+y не являются изменяемыми значениями. Мой вопрос в том, почему оператор + возвращает изменяемое значение lvalue для объектов string , но не для int ?

    
задан James Fan 14.08.2015 в 14:15
источник
  • В C ++ объекты являются экземплярами любого типа, включая встроенные типы. И типы - это типы. Таким образом, «объекты» и «встроенные типы» не имеют смысла. –  juanchopanza 14.08.2015 в 14:22
  • @juanchopanza Было бы полезно указать правильную формулировку, пока вы на ней :) –  Quentin 14.08.2015 в 14:43
  • @Quentin Я думаю, что «разница между встроенными типами и определенными пользователем типами» будет точной. –  juanchopanza 14.08.2015 в 15:33

2 ответа

20

Он не возвращает модифицируемое значение lvalue для строки. Он возвращает временный объект, а s1+s2 и x+y - оба значения r.

Однако объекты типа класса могут перегружать operator= , что и string . Вам разрешено вызывать функции-члены на rvalues.

Разница между двумя случаями заключается в = (не + )

    
ответ дан M.M 14.08.2015 в 14:19
  • Обратите внимание, что это проблема, над которой работает. Вы можете запретить вызов оператора = по rvaliues ваших собственных классов. Проблема в том, что существует существующий код, который сломался бы, если бы стандарт C ++ был изменен, чтобы запретить присвоение std :: string rvalues. –  MSalters 14.08.2015 в 16:50
  • @MSalters Да, мудрый человек однажды спросил то же самое .. :) –  M.M 15.08.2015 в 04:38
14

Для std::string , s1 + s2 = s3 фактически:

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

s1 + s2 возвращает значение rvalue

Методы участников могут применяться и к временным.
Поскольку C ++ 11, у нас есть определитель lvalue / rvalue для метода,
поэтому вы можете запретить o1 + o2 = o3 для своего настраиваемого типа с помощью:

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

, поэтому Object::operator = может применяться только к lvalue.

    
ответ дан Jarod42 14.08.2015 в 14:34