Почему + = допустимые временные значения в стандартной библиотеке? - PullRequest
5 голосов
/ 08 марта 2012

Когда я пытаюсь скомпилировать следующее на ideone :

class X
{
  public:
   friend X& operator+=(X& x, const X& y);
};

X& operator+=(X& x, const X& y) { return x; }

int main()
{
  X() += X();
}

Как и ожидалось, это приводит к ошибке компиляции, потому что вы не можете передать временную неконстантную ссылку.

Однако следующие данные успешно компилируются на ideone :

std::string() += std::string();

Разве эта ошибка не похожа на мой пример выше?

Редактировать:

Если std :: string () определяет += как операцию-член, почему он делает это, когда такое использование позволяет левой сторонебыть временным?Почему бы не определить его так, как я описал выше, и избежать ссылки на временные проблемы?

Ответы [ 4 ]

6 голосов
/ 08 марта 2012

Правило C ++ заключается в том, что вы не можете привязать временную ссылку к неконстантной ссылке. Однако вы можете вызывать неконстантные функции-члены для временных переменных: если вы определили operator +=() как член, вы можете вызвать его для своего объекта. Это один из приемов, как получить временную ссылку, например, при использовании временного std::istringstream для чтения неосновного типа (базовые типы читаются членами):

std::string word;
if (std::istringstream("hello world") >> std::ws >> word) { ... }

(да, это - глупый пример).

3 голосов
/ 08 марта 2012
string& operator+= ( const string& str ); 

почувствуй разницу

3 голосов
/ 08 марта 2012

Потому что это const.

строка :: оператор + =

Если изменить на X& operator+=(const X& y), ваш код также будет хорошо компилироваться.

редактировать

Вы изменили вопрос после того, как я уже ответил на него, и изменили определение вашей X::operator+= на функцию friend вместо функции-члена. Это действительно не работает. Обратите внимание, что std::string::operator+= не является friend, это функция-член std::string.

0 голосов
/ 08 марта 2012

operator+= обычно перегружается как функция-член, и функции-члены (const или иначе) могут вызываться для временных значений r .

ЕслиВы измените свою перегрузку на член, X& operator+=(const X&), тогда ваш пример также должен скомпилироваться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...