Мне нужно некоторое заверение о том, когда, присваивая или список инициализируя именованную переменную auto
, с
- A a
std::move
() ed вернул ссылку на переменную
- B возвращаемая ссылка на переменную
, где после выражения источник выходит из области видимости, A безопасен / B небезопасен. Пример кода:
#include <iostream>
#include <string>
#include <deque>
#include <utility>
int main() {
std::deque<std::string> container {"foo"};
auto elementB = container.front(); //B I assume this is unsafe
auto elementA = std::move(container.front());//A I assume this is safe
container.pop_front();
std::cout << "A: " << elementA << " B: " << elementB << "\n";
}
Насколько я понимаю, выражение B генерирует lvalue справа от присваивания, и поэтому тип elementB
является ссылкой lvalue aka std::string&
, поэтому он будет небезопасным.
Также вывод «A: foo B:» при выполнении кода предполагает это. (https://ideone.com/wKKbdK) Обновление: Извините, я забыл, что переместил его, поэтому я изменил порядок, и теперь вывод такой же, как исключение, извините.
Однако гораздо более неприятной вещью, в которой я не уверен, является выражение A: после std::move
я предполагаю, что получил xvalue, который является как rvalue, так и glvalue, поэтому я не уверен, что такое стандартизированное поведение, если таковое имеется, для тип вычета elementA
.
Поскольку из lvalues я почти уверен, что его UB, а lvalues являются glvalues, а xvalues являются их частью, то тип будет elementA
будет std::string&&
, что было бы небезопасно, верно? (за исключением исключения для const && AFAIK)
Итак, подведем итог: Является ли использование элемента A безопасным стандартизированным поведением и каким будет его тип?