LINUX.ORG.RU

Продление жизни rvalue 2

 


0

3

По первой части - жестко туплю, удалил.

Там ссылка на предложенные правки http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0727r0.html (её и в прошлой теме скидывали), я по ним пробежался и чего-то не въехал:

The third context is when a reference is bound to a temporary object. [ Footnote: The same rules apply to initialization of an initializer_list object (8.6.4) with its underlying temporary array. ] The temporary object to which the reference is bound or the temporary object that is the complete object of a subobject to which the reference is bound persists for the lifetime of the reference if the glvalue to which the reference is bound was obtained through one of the following:
...
a const_cast (8.2.11 [expr.const.cast]), static_cast (8.2.9 [expr.static.cast]), dynamic_cast (8.2.7 [expr.dynamic.cast]), or reinterpret_cast (8.2.10 [expr.reinterpret.cast]) converting, without a user-defined conversion, a glvalue operand that is one of these expressions to a glvalue that refers to the object designated by the operand, or to its complete object or a subobject thereof,
...

т.е. S &&s = static_cast<S>(Q), при наличии у Q operator S() - так делать нельзя? Бредом попахивает, но к чему эти слов про user-defined conversion.

Продление жизни rvalue

Опять 25... У rvalue нет (времени) жизни, это класс выражений. Время жизни есть у объектов.

S &&s = static_cast<S>(Q), при наличии у Q operator S() - так делать нельзя? Бредом попахивает, но к чему эти слов про user-defined conversion.

Я думаю, ты пропустил скобки после Q: S &&s = static_cast<S>(Q{}).

В процитированном тобой написано про каст glvalue operand to a glvalue. Каст к не-ссылке это не glvalue, а prvalue:

http://eel.is/c++draft/expr.static.cast#1.sentence-2

If T is an lvalue reference type or an rvalue reference to function type, the result is an lvalue; if T is an rvalue reference to object type, the result is an xvalue; otherwise, the result is a prvalue.

Это prvalue при инициализации ссылки материализуется (http://eel.is/c draft/conv.rval) и время жизни созданного объекта продлевается согласно первого подпункта («a temporary materialization conversion»).

utf8nowhere ★★ ()
Последнее исправление: utf8nowhere (всего исправлений: 1)
Ответ на: комментарий от utf8nowhere

Я вот чего подумал: cppreference говорят, что жизнь продливается при привязке к сылке «temporary». А что такое эта «temporary»? Какая связь с lvalue и прочими категориями выражений имеется? Раньше я думал, что временный объект это полученный от prvalue, а теперь прогнал такой пример

struct T { ~T() { cout << "destruct\n";} };
int main() {
   const T& r = static_cast<const T&>(T{});
   cout << "---------\n";
}
и вижу, что жизнь продливается, хотя выражения lvalue. Наверное на temporary materialization завязано.

pavlick ()
Последнее исправление: pavlick (всего исправлений: 2)

Ну оно понятно )), я о том, что в самом стандарте не очень понятно что такое временный объект (получил ведь я его из lvalue выражения, после этого он ещё временный?). Ну и х. с ним, что-то я сильно заморочился. Можно придумать что-нибудь более реалистичное:

const int &f(const int &r) {return r;}
const int &q = f(4);

pavlick ()
Последнее исправление: pavlick (всего исправлений: 1)
Ответ на: комментарий от anonymous

Я туда и так слишком часто смотрю. Кстати, я вполне здравый вопрос задал, вот смотрите - вот вам и грабли:

struct T { ~T() { cout << "destruct\n";} };
const T &f(const T &r) {return r;}
int main()
{
   const T &q = f({});
   cout << "---------\n";
}
// cout:
// destruct
// ---------
Хотя случай со статик каст идентичный по сути.

pavlick ()
Ответ на: комментарий от anonymous

Тогда и const T& r = static_cast<const T&>(T{}) должен быть ЮБ. Это одинаковые примеры по своей сути.

a temporary bound to a reference parameter in a function call exists until the end of the full expression containing that function call

pavlick ()
Последнее исправление: pavlick (всего исправлений: 2)
Ответ на: комментарий от anonymous

Да, я не прав, наверное. Там ведь были перечислены места из которых glvalue, годится для продления жизни. Но это не интуитивно, лучше было бы иметь одинаковые правила для всех ситуаций, а не в целом нельзя, но вот вам десяток исключений из правила. На этом закончу, благодарю за ответы.

pavlick ()
Ответ на: комментарий от pavlick

Я вот чего подумал: cppreference говорят, что жизнь продливается при привязке к сылке «temporary». А что такое эта «temporary»?

Было такое неаккуратное словоупотребление в стандарте. Просто «temporary», «temporary object» и «temporary expression». Под «temporary» понимался обычно «temporary object», под «temporary expression» — prvalue.

P0727 заменил «temporary» на «temporary object», а словосочетание «temporary expression» — кандидат на удаление.

Наверное на temporary materialization завязано.

Да. Каст к ссылочному типу prvalue-аргумента приводит к temporary materialization.

Стоит помнить, что temporary materialization conversion появилось в C++17, вместе со сменой определений для Zvalues, для реализации так называемого guaranteed copy elision.

utf8nowhere ★★ ()