будет повисшая ссылка,мотивируя это тем, что temporary timelife extension не работает через rvalue
Я читал последний стандарт п. 6.10 про glvalue, prvalue, rvalue и xvalue
так же п. 15.2 про расширение времени жизни переменной, и не смог связать стандарт и утверждения коллеги.
Буду благодарен, если вы объясните мне вопрос, желательно с опорой на стандарт. Возможно, я просто плохо перевожу и распарсиваю наш главный мануал.
Здравствуйте, andyp, Вы писали:
A>Секция Lifetime of a temporary.
(since C++20)
struct A {
int&& r;
};
A a1{7}; // OK, lifetime is extended
A a2(7); // well-formed, but dangling reference
OMG! Кто-нибудь может мне объяснить зачем понадобилось расширять инициализацию с круглыми скобками? Чтобы было легче допустить ошибку забыв написать конструктор?
Здравствуйте, B0FEE664, Вы писали:
BFE>OMG! Кто-нибудь может мне объяснить зачем понадобилось расширять инициализацию с круглыми скобками? Чтобы было легче допустить ошибку забыв написать конструктор?
Расширять на агрегаты? Имхо как раз за тем, чтобы меньше писать тривиального кода. Ну любит народ круглые скобочки , хочет инициализировать так же как и классы с конструктором.
Здравствуйте, andyp, Вы писали:
A>Расширять на агрегаты? Имхо как раз за тем, чтобы меньше писать тривиального кода. Ну любит народ круглые скобочки , хочет инициализировать так же как и классы с конструктором.
Ну не знаю. Можно же использовать фигурные, тем более, что теперь можно указывать названия полей:
struct A
{
int x;
int y;
};
A pt{ .x= 2, .y = 3 };
BFE>Хмм. А разве, формально, это не использование переменной pt до её инициализации?
[basic.life]/6 говорит что получать доступ к non-static data members или вызывать non-static member functions через указатель на объект чей lifetime не начался это UB.
[basic.life]/7 описывает поведение glvalues, ссылающихся на объект, чей lifetime не начался. И там UB только если вызывать функции, но не получать доступ к data members.
Здравствуйте, B0FEE664, Вы писали:
BFE>Здравствуйте, andyp, Вы писали:
A>>Расширять на агрегаты? Имхо как раз за тем, чтобы меньше писать тривиального кода. Ну любит народ круглые скобочки , хочет инициализировать так же как и классы с конструктором.
BFE>Ну не знаю. Можно же использовать фигурные, тем более, что теперь можно указывать названия полей:
Народ имхо привык к старым правилам преобразования типов и хочет продолжать ими пользоваться. А случае фигурных скобок правила пожестче.
BFE>Вот чего не хватает, так это такого: BFE>
BFE>A pt{ .x= 2, .y = .x };
BFE>
Когда читал про это, тоже думал, что мне этого не хватает. Но вот как-то обхожусь. Сам не знаю почему, но у меня простенькие агрегаты с малым количеством полей получаются
Здравствуйте, andyp, Вы писали:
A>Здравствуйте, Molchalnik, Вы писали:
M>>Буду благодарен, если вы объясните мне вопрос, желательно с опорой на стандарт. Возможно, я просто плохо перевожу и распарсиваю наш главный мануал.
A>Если подойдёт объяснение с cppreference, то оно здесь: A>https://en.cppreference.com/w/cpp/language/reference_initialization
A>Секция Lifetime of a temporary.
вот это ключевое для вопроса из приведённого источника
In general, the lifetime of a temporary cannot be further extended by "passing it on": a second reference, initialized from the reference to which the temporary was bound, does not affect its lifetime.
В общем случае, нельзя рассчитывать на сквозное продление времени жизни временных переменных: уже на вторая ссылка, инициализированная от той, к которой временная переменная была привязана в первые, не влияет на её[временной переменной] время жизни.
Это почти всё делает ясным, но хотелось бы ссылочку на стандарт
Здравствуйте, Molchalnik, Вы писали:
M>вот это ключевое для вопроса из приведённого источника M>
M>In general, the lifetime of a temporary cannot be further extended by "passing it on": a second reference, initialized from the reference to which the temporary was bound, does not affect its lifetime.
M>Это почти всё делает ясным, но хотелось бы ссылочку на стандарт
The lifetime of a temporary bound to the returned value in a function return statement ([stmt.return]) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, Molchalnik, Вы писали:
M>>вот это ключевое для вопроса из приведённого источника M>>
M>>In general, the lifetime of a temporary cannot be further extended by "passing it on": a second reference, initialized from the reference to which the temporary was bound, does not affect its lifetime.
R>The lifetime of a temporary bound to the returned value in a function return statement ([stmt.return]) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
спасибо! Но есть ещё утверждение автора примера о том, что у rvalue не возможно расширить время жизни, только скопировать. Если на 6.11 я ещё натыкался, то вот про rvalue я вообще ничего не нашёл.
R>>The lifetime of a temporary bound to the returned value in a function return statement ([stmt.return]) is not extended; the temporary is destroyed at the end of the full-expression in the return statement.
M>спасибо! Но есть ещё утверждение автора примера о том, что у rvalue не возможно расширить время жизни, только скопировать. Если на 6.11 я ещё натыкался, то вот про rvalue я вообще ничего не нашёл.
Я думаю, здесь имеет место какое-то не совсем верное толкование его высказываний. Во-первых, заметно некоторое размытие терминологии: в контескте обсуждения продления времени жизни речь идет всегда о времени жизни временных объектов. Которые материализуются как раз при биндинге ссылок именно к rvalue выражениям (prvalue, если быть точным):
The materialization of a temporary object is generally delayed as long as possible in order to avoid creating unnecessary temporary objects. [
Note: Temporary objects are materialized:
— when binding a reference to a prvalue
— . . .
А во-вторых, важным является то, что (какая-то) ссылка биндится к временному объекту, какая именно это ссылка (rvalue или lvalue), совсем не важно. Поэтому rvalue ссылка способна продлевать время жизни временного объекта с тем же успехом, что и константная lvalue ссылка. И в этой же главе можно найти примеры:
template<typename T> using id = T;
int i = 1;
int&& a = id<int[3]>{1, 2, 3}[i]; // temporary array has same lifetime as aconst int& b = static_cast<const int&>(0); // temporary int has same lifetime as bint&& c = cond ? id<int[3]>{1, 2, 3}[i] : static_cast<int&&>(0);
// exactly one of the two temporaries is lifetime-extended
--
Не можешь достичь желаемого — пожелай достигнутого.
BFE>Хмм. А разве, формально, это не использование переменной pt до её инициализации?
Подозреваю, здесь то же правило, что и на списках инициализации внутри конструкторов — играет роль лишь порядок описания полей класса, но никак не порядок упоминания инициализаторов. Т.е. если в описании поле "игрек" идёт после поля "икс", то такой финт легален, т.к. "pt.x" уже будет проинициализирован первым, даже если мы напишем так:
A pt { .y = pt.x, .x = 2 };
Но это лишь интуитивное подозрение, конечно. Ибо пути Комитета неисповедимы...