Зачем возвращают по значению, rvalue параметр
От: Serjio Россия  
Дата: 12.03.14 15:01
Оценка:
Функция, принимающая rvalue-ссылку
(на объект, для которого реализована move semantics, и лишнее копирование которого дорого),
которая должна изменить значение, объекта, полученного по этой rvalue-ссылке,
и вернуть результат своей работы.

Вопрос:
Почему, в этом случае, возвращают по значению ?


string f(string&& s)
{
   if (s.size())
      s[0] = toupper(s[0]);
   return s;
}

Как Страуструп в 4-м издании, так и в стандартной библиотеке.


Почему не вернуть rvalue-ссылку ?
Какие в этом случае могут быть грабли ?


string&& f(string&& s)
{
   if (s.size())
      s[0] = toupper(s[0]);
   return std::move(s);
}


Если есть вызов такой функции, то объект полученный по rvalue,
всегда будет жить до конца полного выражения. Иначе никак не будет.

Понятно, что в первом случае, можно сказать: семантика перемещения же есть,
и инициализация возвращаемого значения, не будет дорогой.

Но зачем еще одно, пусть и маленькое, но отдельное, "вместилище" для объекта.

адрес на область памяти никому больше ненужного объекта получили — там изменили значение — и вернули дальше, этот адрес

объект (содержащий значение) как был временный, так и остался (после вызова функции)

стек же не лишний, да и несколько mov добавляется
Только на РСДН помимо ответа на вопрос, можно получить еще список орфографических ошибок и узнать что-то новое из грамматики английского языка (c) http://www.rsdn.ru/forum/cpp/4720035.1.aspx
Автор: ZOI4
Дата: 28.04.12
Re: Зачем возвращают по значению, rvalue параметр
От: andyp  
Дата: 12.03.14 18:03
Оценка: 3 (1) +1
//как-то так.
auto&& s = f(std::string("oops!")); //получаем висящу ссылку
Re: Зачем возвращают по значению, rvalue параметр
От: lxa http://aliakseis.livejournal.com
Дата: 13.03.14 07:15
Оценка: 2 (1) +1
S>Почему не вернуть rvalue-ссылку ?
S>Какие в этом случае могут быть грабли ?

Вкратце, те же, что и с lvalue-ссылками.
Re: Зачем возвращают по значению, rvalue параметр
От: Abyx Россия  
Дата: 13.03.14 09:29
Оценка:
Здравствуйте, Serjio, Вы писали:

S>Функция, принимающая rvalue-ссылку

S>(на объект, для которого реализована move semantics, и лишнее копирование которого дорого),
S>которая должна изменить значение, объекта, полученного по этой rvalue-ссылке,
S>и вернуть результат своей работы.

S>Вопрос:

S>Почему, в этом случае, возвращают по значению ?

S>

S>string f(string&& s)
S>{
S>   if (s.size())
S>      s[0] = toupper(s[0]);
S>   return s;
S>}


rvalure-ссылки нужны только для параметров, и они как следует из названия являются ссылками на rvalure, т.е. на временные объекты.
т.е. такая функция принимает временный объект, и возвращать ссылку на временный объект — опасно.
возвращать rvalure-ссылку бессмысленно, т.к. возвращаемое значение — это временный объект, и он и так будет браться по rvalure-ссылке
In Zen We Trust
Re[2]: Зачем возвращают по значению, rvalue параметр
От: B0FEE664  
Дата: 13.03.14 09:36
Оценка: 3 (1) +1
Здравствуйте, andyp, Вы писали:

A>//как-то так.

A>auto&& s = f(std::string("oops!")); //получаем висящу ссылку

Хмм. А вот тут рядом ссылаются на http://en.cppreference.com/w/cpp/language/reference, где на доступном английском пишут, что

Rvalue references can be used to extend the lifetime of a modifiable temporary (note, lvalue references to const can extend lifetimes too, but they are not modifiable)

#include <iostream>
#include <string>
int main()
{
    std::string s1 = "Test";
//    std::string&& r1 = s1; // error: can't bind to lvalue
 
    const std::string& r2 = s1 + s1; // OK, lvalue ref to const extends lifetime
//    r2 += "Test"; // error: can't modify through reference to const
 
    std::string&& r3 = s1 + s1; // OK, rvalue ref extends lifetime
    r3 += "Test"; // this rvalue can be modified
    std::cout << r3 << '\n';
}


Можете прокомментировать?
И каждый день — без права на ошибку...
Re[2]: Зачем возвращают по значению, rvalue параметр
От: Abyx Россия  
Дата: 13.03.14 09:47
Оценка: -1
Здравствуйте, andyp, Вы писали:

A>//как-то так.

A>auto&& s = f(std::string("oops!")); //получаем висящу ссылку

не получаем, ссылки увеличивают время жизни временных объектов в выражении до конца scope.

а вот с указателем — будет плохо:
std::string* s = &f(std::string("oops!"));
In Zen We Trust
Re[3]: Зачем возвращают по значению, rvalue параметр
От: andyp  
Дата: 13.03.14 10:03
Оценка: 3 (1)
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, andyp, Вы писали:



BFE>Можете прокомментировать?


Могу, но не очень уверенно, так как в стандарт не смотрел. Если инициализируешь ссылкой, то получаешь висящую ссылку, если объектом — то его время жизни продляется.

http://stackoverflow.com/questions/3716277/do-rvalue-references-allow-dangling-references

В случае функции, возращающей rvalue reference по-моему наблюдается первый случай.
Re[3]: Зачем возвращают по значению, rvalue параметр
От: uzhas Ниоткуда  
Дата: 13.03.14 10:07
Оценка: +1
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, andyp, Вы писали:


A>>//как-то так.

A>>auto&& s = f(std::string("oops!")); //получаем висящу ссылку

A>не получаем, ссылки увеличивают время жизни временных объектов в выражении до конца scope.


если f возвращает std::string&&, то получаем висячую ссылку
ссылка auto&& продлила бы жизнь временному объекту в случае, если бы f возвращала именно временный объект

аналогичное верно для обычных константных ссылок:
A f(const A& a)
{
  return a;
}

const A& g(const A& a)
{
  return a;
}

const A& a1 = f(A()); // временный объект, который возвращается из функции, будет захвачен константной ссылкой и будет уничтожен при выходе из scope
const A& a2 = g(A()); // вот тут будет висячая ссылка, т.к. функция g вернет ссылку (пусть и константную) на исходный временный объект, время жизни которого ограничено выражением, ссылка не зацепится за него


зы: рассуждаю логически, в стандарт не глядел, поэтому могу ошибаться
Re[3]: ответил выше (-)
От: andyp  
Дата: 13.03.14 10:10
Оценка:
Re[3]: Зачем возвращают по значению, rvalue параметр
От: jazzer Россия Skype: enerjazzer
Дата: 13.03.14 10:14
Оценка: +1
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, andyp, Вы писали:


A>>//как-то так.

A>>auto&& s = f(std::string("oops!")); //получаем висящу ссылку

A>не получаем, ссылки увеличивают время жизни временных объектов в выражении до конца scope.


имхо, нет.
Ссылка продлит время жизни, если f вернет временный объект по значению.
А если f вернет ссылку, то ничего продлеваться не будет — откуда вызывающему коду знать, на что эта ссылка указывает?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Зачем возвращают по значению, rvalue параметр
От: smeeld  
Дата: 13.03.14 10:31
Оценка:
Здравствуйте, Serjio, Вы писали:

#include <iostream>
#include <string>
using namespace std;
 string f(string&& s){

  s[0]=toupper(s[0]);

   return move(s);
};

 int main(int c, char** s){

     string st1(s[1]);
 
 cout<<"RES=="<<f(move(st1)).c_str()<<endl;

};
----------------------------------------
[root@localhost g]# ./vv der
RES==
=================================================================================================
#include <iostream>
#include <string>
using namespace std;
 string f(string&& s){

  s[0]=toupper(s[0]);

   return s;
};

 int main(int c, char** s){

     string st1(s[1]);
 
 cout<<"RES=="<<f(move(st1)).c_str()<<endl;

};
-------------------------------------
[root@localhost g]# ./vv der
RES==Der
Re[2]: Зачем возвращают по значению, rvalue параметр
От: Serjio Россия  
Дата: 13.03.14 13:39
Оценка:
Здравствуйте, smeeld, Вы писали:

в версии, возвращающей "по значению", я std::move() не использовал


string f(string&& s)
{
   if (s.size())
      s[0] = toupper(s[0]);
   return s;
}
Только на РСДН помимо ответа на вопрос, можно получить еще список орфографических ошибок и узнать что-то новое из грамматики английского языка (c) http://www.rsdn.ru/forum/cpp/4720035.1.aspx
Автор: ZOI4
Дата: 28.04.12
Re[3]: Зачем возвращают по значению, rvalue параметр
От: Erop Россия  
Дата: 13.03.14 14:41
Оценка:
Здравствуйте, Abyx, Вы писали:

A>>auto&& s = f(std::string("oops!")); //получаем висящу ссылку


A>не получаем, ссылки увеличивают время жизни временных объектов в выражении до конца scope.


А ты уверен, что в данном случае они таки увеличивают?..

Как не имея доступа к определению f узнать, что то, что она варнула -- это ссылка на то, что в неё передали?

A>а вот с указателем — будет плохо:

A>std::string* s = &f(std::string("oops!"));

А разве так можно?..
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Зачем возвращают по значению, rvalue параметр
От: Abyx Россия  
Дата: 13.03.14 15:03
Оценка: :)
Здравствуйте, Erop, Вы писали:

A>>>auto&& s = f(std::string("oops!")); //получаем висящу ссылку

A>>не получаем, ссылки увеличивают время жизни временных объектов в выражении до конца scope.
E>А ты уверен, что в данном случае они таки увеличивают?..
E>Как не имея доступа к определению f узнать, что то, что она варнула -- это ссылка на то, что в неё передали?

ок, наверное пора смотреть стандарт:

12.2 Temporary objects [class.temporary]
4 There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression. [...]
5 The second context is when a reference is bound to a temporary. The temporary to which the reference is
bound or the temporary that is the complete object of a subobject to which the reference is bound persists
for the lifetime of the reference except:
[...]
— A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of
the full-expression containing the call.


— действительно, привязка к ссылке продлевает жизнь только того временного объекта который был привязан.

A>>а вот с указателем — будет плохо:

A>>std::string* s = &f(std::string("oops!"));
E>А разве так можно?..
неа, нельзя. но если хочется, можно как-то взять указатель от временной переменной
In Zen We Trust
Re[5]: Зачем возвращают по значению, rvalue параметр
От: Erop Россия  
Дата: 13.03.14 15:26
Оценка:
Здравствуйте, Abyx, Вы писали:

A>- действительно, привязка к ссылке продлевает жизнь только того временного объекта который был привязан.

A>неа, нельзя. но если хочется, можно как-то взять указатель от временной переменной

Окей, не прав оба раза!
Теперь, я щитаю, ты должен встать на колени, и трижды отсказать: "героям С++ слава!", а то неактуальненько выйдет
Но в целом, если без шуток, предлагаю не ругать там нубов или не нубов, сначала разобраться хотя бы самому, а потом уже критиковать коллег?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Зачем возвращают по значению, rvalue параметр
От: Abyx Россия  
Дата: 13.03.14 16:52
Оценка:
Здравствуйте, Erop, Вы писали:

E>Но в целом, если без шуток, предлагаю не ругать там нубов или не нубов, сначала разобраться хотя бы самому, а потом уже критиковать коллег?


вот если бы нубы и не нубы сами сходили в стандарт — я бы может задумался,
хотя всеравно, форум он больше для фана чем для решения проблем и т.п.
In Zen We Trust
Re[2]: Зачем возвращают по значению, rvalue параметр
От: niXman Ниоткуда https://github.com/niXman
Дата: 13.03.14 17:11
Оценка:
Здравствуйте, smeeld, Вы писали:

S>[root@localhost g]# ./vv der

сурово, работать под рутом =)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[3]: Зачем возвращают по значению, rvalue параметр
От: zaufi Земля  
Дата: 13.03.14 17:45
Оценка:
Здравствуйте, niXman, Вы писали:

X>Здравствуйте, smeeld, Вы писали:


S>>[root@localhost g]# ./vv der

X>сурово, работать под рутом =)

ну может коллега сидит за суровым хостом, где обычным пользователям нельзя компилячить и запускать всякий хлам (в целях безопасности конечно же)... вот он и рутом польузется для этого %) а то мало ли каких local exploitов всяким пользователям захочется собрать и "поиграть"...
Re[4]: вот ответ на мой вопрос
От: Serjio Россия  
Дата: 13.03.14 17:51
Оценка:
Здравствуйте, andyp, Вы писали:

>http://stackoverflow.com/questions/3716277/do-rvalue-references-allow-dangling-references

вот ответ на мой вопрос

вся страница целиком
и особенно комментарии sellibitze от Sep 15 '10 at 9:32 и FredOverflow от Sep 15 '10 at 10:23




можно сказать еще так:

Когда T&& инициализируется, prvalue expresion-ном — создается temporary объект.
Который bound-ится с инициализируемой ссылкой.
И lifetime созданного temporary объекта, есть lifetime инициализированной им ссылки.

Когда T&& инициализируется, xvalue expresion-ном — никакой temporary объект не создается.
А время жизни инициализированной ссылки, не на кого не влияет.

lifetime содержимого в xvalue, определяется lifetime-мом того что там лежит.
А lifetime, инициализируемой T&& ссылки, на lifetime объкта из xvalue никак не влияет. И повлиять никак не может и не должен.


---------


пока были только const T&, и не было возможности возвращать T&&, все было просто и понятно (как не нарваться на UB).


меня confused фраза, что rvalue references, "продляют" время жизни временного объекта.

Как "продляют", а где в этом случае живет временный объект. вроде как должен быть на стеке, а как тогда ему время жизни продляется ?
А если несколько T&& ссылок, будут ссылаться на одно и тоже,
то что получается, продлятся будет, по времени жизни самой дальней rvalue ссылки ?

В общем, была неразбериха, и какой-то мистически забавный способ, того как это сделано.

Ну теперь, все прояснилось и встало на свои места.
Чему рад.



Спасибо
Только на РСДН помимо ответа на вопрос, можно получить еще список орфографических ошибок и узнать что-то новое из грамматики английского языка (c) http://www.rsdn.ru/forum/cpp/4720035.1.aspx
Автор: ZOI4
Дата: 28.04.12
Re[4]: Зачем возвращают по значению, rvalue параметр
От: smeeld  
Дата: 13.03.14 18:13
Оценка:
Здравствуйте, zaufi, Вы писали:

> а то мало ли каких local exploitов всяким пользователям захочется собрать и "поиграть"...


Шизой не страдаю, и грибов как мышъх не употребляю, я один пока.
А под рутом только сессия терминала, потому что для всяких манипуляций
в системе всё равно нужен рут, а sudo презираю.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.