Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ С\С++ _ Изменение значения возвращаемого из функции

Автор: Quester 2.6.2017, 20:37

Добрый вечер, ребята! Объясните пожалуйста, как такое работает:

...
std::string getStr(){
   reutrn "hello";
}

int main(){

   getStr() = "World!";
...


Из функции "getStr()" вернется временная переменная, скажите пожалуйста, разве можно изменять значение временной переменной? И насколько это корректно??

Спасибо!!!

Автор: Iron Bug 2.6.2017, 21:34

в том виде, как ты написал, это не работает.
если хочешь присваивать результат значению, возвращаемому из функции, результат должен иметь тип lvalue, то есть, возвращаться по ссылке.
типичное применение возврата ссылки - operator[].

Автор: Quester 3.6.2017, 13:07

Цитата(Iron Bug @ 2.6.2017, 21:34) *
в том виде, как ты написал, это не работает.
если хочешь присваивать результат значению, возвзащаемому из функции, результат должен иметь тип lvalue, то есть, возвращаться по ссылке.
типичное применение возврата ссылки - operator[].

Если написать так, то работает-
...
cout<<(getStr() = "Wolrd");
...

, напишет "World". Просто не понятно, как компилируется, мы же rvalue значение присваиваем, а это нельзя вроде?

Спасибо за ответ!!!

Автор: Алексей1153 3.6.2017, 20:22

"работает" это так

1) getStr() возвращает объект класса std::string (безымянный, но назовём его, скажем, S). S содержит значение "hello"

2) вызывается оператор = объекта S , присваивается значение "Wolrd"
3) (getStr() = "Wolrd") возвращает ссылку на S
4) S выводится в поток

Автор: lanz 4.6.2017, 1:26

Цитата(Алексей1153 @ 3.6.2017, 20:22) *
"работает" это так

Не совсем :)
Вот так не скомпилируется:
int getInt() {
  return 42;
}

int main(int argc, char **argv) {
  getInt() = 15;
}


Цитата(Гость_Quester_* @ 3.6.2017, 13:07) *
мы же rvalue значение присваиваем, а это нельзя вроде?

Это верно, но не совсем, т.к. возвращается объект класса std::string, то assignment превращается в вызов member function и prvalue превращается в xvalue.
Называется temporary materialization.
http://en.cppreference.com/w/cpp/language/implicit_conversion#Temporary_materialization

Автор: Гест 29.8.2017, 15:20

Цитата(lanz @ 4.6.2017, 1:26) *
Не совсем

Что он описал неверно?

Автор: lanz 30.8.2017, 16:21

Цитата
Что он описал неверно?

Пропустил превращение prvalue в xvalue, я же все описал.

Автор: Гест 30.8.2017, 19:40

Цитата(lanz @ 30.8.2017, 16:21) *
Цитата
Что он описал неверно?

Пропустил превращение prvalue в xvalue, я же все описал.

А ты опустил байндинг аргумента оператора=

Автор: Алексей1153 31.8.2017, 7:34

хех, нашли, о чём спорить

Автор: lanz 31.8.2017, 10:34

Цитата
А ты опустил байндинг аргумента оператора=

this? он конвертируется в xvalue до байндинга, так что это тут не причем
"world"? а что необычного в байндинге const char* ?

Превращение prvalue в xvalue имеет непосредственное отношение к сути вопроса и объясняет механизм, поэтому я его и описал, байндинг аргументов не имеет к ней отношения. Если считаете обратное, разверните свою точку зрения более подробно.
Алексей1153 все в целом верно описал, кроме того что из функции возвращается не временное значение, а prvalue, о чем спрашивал ТС
Цитата
мы же rvalue значение присваиваем, а это нельзя вроде?

Поэтому я и посчитал возможным рассказать о механизме temporary materialization.

Цитата
хех, нашли, о чём спорить

https://imgs.xkcd.com/comics/duty_calls.png

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)