range based for и временные объекты
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.09.22 23:06
Оценка: +1 :)
Здравствуйте!

Вот тут только подумал, что:
for(auto i: n.items())
{
    //...
}

это удобно, а cppreference говорит, что это плохо

This problem may be worked around using init-statement:

for (T thing = foo(); auto& x : thing.items()) { /* ... */ } // OK

Неудобно же?
Маньяк Робокряк колесит по городу
Re: range based for и временные объекты
От: DiPaolo Россия  
Дата: 05.09.22 01:45
Оценка:
Ну нет же. Там речь про другое:

If range-expression returns a temporary, its lifetime is extended until the end of the loop, as indicated by binding to the forwarding reference __range, but beware that the lifetime of any temporary within range-expression is not extended.

for (auto& x : foo().items()) { /* .. */ } // undefined behavior if foo() returns by value


То есть это замечание как раз про случай, когда ты вызываешь foo(), а потом берешь его айтемсы foo().items() и все это в рейндж фор.
Патриот здравого смысла
Re[2]: range based for и временные объекты
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 05.09.22 10:47
Оценка:
Здравствуйте, DiPaolo, Вы писали:

DP>

DP>If range-expression returns a temporary, its lifetime is extended until the end of the loop, as indicated by binding to the forwarding reference __range, but beware that the lifetime of any temporary within range-expression is not extended.
DP>

DP>for (auto& x : foo().items()) { /* .. */ } // undefined behavior if foo() returns by value
DP>


DP>То есть это замечание как раз про случай, когда ты вызываешь foo(), а потом берешь его айтемсы foo().items() и все это в рейндж фор.


Да, ьыл не совсем прав. Не понятно, а какая разница?
Маньяк Робокряк колесит по городу
Re[3]: range based for и временные объекты
От: DiPaolo Россия  
Дата: 05.09.22 11:00
Оценка:
M>Да, ьыл не совсем прав. Не понятно, а какая разница?

If range-expression returns a temporary, its lifetime is extended until the end of the loop, as indicated by binding to the forwarding reference __range, but beware that the lifetime of any temporary within range-expression is not extended.


То есть, если имеем:

T thing = foo();
for (auto& x : thing.items()) { /* ... */ }


То это ок, т.к. временный объект, возвращенный thing.items() будет жить до конца цикла.

В случае же
for (auto& x : foo().items()) { /* ... */ }


foo() может также вернуть вернуть временный объект, который полбе вычисления foo().items() может быть удален, соответственно, то, что он успеет вернуть из items(), может протухнуть и вызвать UB.
Патриот здравого смысла
Re: range based for и временные объекты
От: Андрей Тарасевич Беларусь  
Дата: 08.09.22 15:46
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>Вот тут только подумал, что:

M>
for(auto i: n.items())
M>{
M>    //...
M>}

M>это удобно, а cppreference говорит, что это плохо

M>

M>This problem may be worked around using init-statement:
M>

for (T thing = foo(); auto& x : thing.items()) { /* ... */ } // OK
M>

M>Неудобно же?

Не понял. Как то, что говорит cppreference, относится к вашему конкретному примеру? В cppreference речь идет о промежуточных временных объектах. В вашем примере промежуточных временных объектов нет.
Best regards,
Андрей Тарасевич
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.