Сообщение Re[6]: MSVC: A non-const reference may only be bound to an l от 26.07.2023 14:03
Изменено 26.07.2023 14:06 Sm0ke
Re[6]: MSVC: A non-const reference may only be bound to an l
Здравствуйте, so5team, Вы писали:
S>Это да. Но поинт в том, что пока std::max работает, у вас валидная ссылка. Иначе бы вот такой вот пример не работал бы:
S>
S>Но он работает.
S>Потому что в выражении, где std::max вызываются, ссылки валидные. Но когда выражение завершается, уничтожаются все временные объекты, созданные в процессе его выполнения, поэтому ссылка и протухает.
S>Именно из-за этого ссылку нельзя сохранять. Но вот передать ее в конструктор объекта (как в примере) можно, т.к. она все еще валидная.
Понял, спасибо.
Но вот в чём могут быть подводные камни с предложением сделать так из исходной задачи
Результат оператора << в таком виде нельзя напрямую передать в range for
И придётся писать более длинно, чтобы ссылка не провисла
S>Это да. Но поинт в том, что пока std::max работает, у вас валидная ссылка. Иначе бы вот такой вот пример не работал бы:
S>
S>#include <string>
S>#include <iostream>
S>using namespace std::string_literals;
S>int main()
S>{
S> auto v = std::max(std::max(std::max("One"s, "Two"s), "Three"s), "Zero"s);
S> std::cout << v << std::endl;
S>}
S>
S>Но он работает.
S>Потому что в выражении, где std::max вызываются, ссылки валидные. Но когда выражение завершается, уничтожаются все временные объекты, созданные в процессе его выполнения, поэтому ссылка и протухает.
S>Именно из-за этого ссылку нельзя сохранять. Но вот передать ее в конструктор объекта (как в примере) можно, т.к. она все еще валидная.
Понял, спасибо.
Но вот в чём могут быть подводные камни с предложением сделать так из исходной задачи
typedef std::set<unsigned> UnsignedSet;
inline
UnsignedSet&& operator<<(UnsignedSet &&us, unsigned u)
{
us.insert(u);
return std::move(us);
}
Результат оператора << в таком виде нельзя напрямую передать в range for
for(
unsigned it : (UnsignedSet{} << 2u << 10u)
) {}
И придётся писать более длинно, чтобы ссылка не провисла
for(
UnsignedSet res = (UnsignedSet{} << 2u << 10u) // не rvalue
unsigned it : res
) {}
Re[6]: MSVC: A non-const reference may only be bound to an l
Здравствуйте, so5team, Вы писали:
S>Это да. Но поинт в том, что пока std::max работает, у вас валидная ссылка. Иначе бы вот такой вот пример не работал бы:
S>
S>Но он работает.
S>Потому что в выражении, где std::max вызываются, ссылки валидные. Но когда выражение завершается, уничтожаются все временные объекты, созданные в процессе его выполнения, поэтому ссылка и протухает.
S>Именно из-за этого ссылку нельзя сохранять. Но вот передать ее в конструктор объекта (как в примере) можно, т.к. она все еще валидная.
Понял, спасибо.
Но вот в чём могут быть подводные камни с предложением сделать так из исходной задачи
Результат оператора << в таком виде нельзя напрямую передать в range for
И придётся писать более длинно, чтобы ссылка не провисла
В случае с UnsignedSet operator<< использовать проще, не опасаясь не правильно использовать либу.
S>Это да. Но поинт в том, что пока std::max работает, у вас валидная ссылка. Иначе бы вот такой вот пример не работал бы:
S>
S>#include <string>
S>#include <iostream>
S>using namespace std::string_literals;
S>int main()
S>{
S> auto v = std::max(std::max(std::max("One"s, "Two"s), "Three"s), "Zero"s);
S> std::cout << v << std::endl;
S>}
S>
S>Но он работает.
S>Потому что в выражении, где std::max вызываются, ссылки валидные. Но когда выражение завершается, уничтожаются все временные объекты, созданные в процессе его выполнения, поэтому ссылка и протухает.
S>Именно из-за этого ссылку нельзя сохранять. Но вот передать ее в конструктор объекта (как в примере) можно, т.к. она все еще валидная.
Понял, спасибо.
Но вот в чём могут быть подводные камни с предложением сделать так из исходной задачи
typedef std::set<unsigned> UnsignedSet;
inline
UnsignedSet&& operator<<(UnsignedSet &&us, unsigned u)
{
us.insert(u);
return std::move(us);
}
Результат оператора << в таком виде нельзя напрямую передать в range for
for(
unsigned it : (UnsignedSet{} << 2u << 10u)
) {}
И придётся писать более длинно, чтобы ссылка не провисла
for(
UnsignedSet res = (UnsignedSet{} << 2u << 10u) // не rvalue, а move constructor
unsigned it : res
) {}
В случае с UnsignedSet operator<< использовать проще, не опасаясь не правильно использовать либу.