Кажется, что оба ответа верны, я просто добавляю абзац из стандарта, который объясняет, почему правильно использовать std::move()
в строке #6
и строке #13
и почему это lvalue, даже если тип является Значение в строке #6
.
Тип выражения - это тип идентификатора. Результатом является объект, обозначенный идентификатором. Результатом является lvalue, если объект является функцией, переменной или элементом данных, и prvalue в противном случае.
5.1.1 [expr.prim.general] / 8
Таким образом, применяя это правило из стандарта, мы можем надеяться, что наши ответы будут правильными.
* именующие 1016 *
// move_me is identifier of a variable denotes to itself the result is lvalue
std::string move_me = "Some string";
Rvalue
// constructing temporary e.g no identifier is an rvalue
std::string("Some string") ;
* именующие 1026 *
// the variable data has type rvalue reference to move_ms, it denotes entity move_ms
// the result is lvalue
void set_data(std::string&& data);
lvalue
// the variable data has type lvalue reference to move_ms,
//it denotes entity move_ms the result is lvalue
void set_data(std::string& data);
lvalue или rvalue - Универсальные ссылки
//the variable data has type universal reference it either holds lvalue or rvalue
template<typename T> void setdata(T && data) ;
Итак, ссылка на rvalue не является rvalue, все может пойти не так
Base(Base const & rhs); // non-move semantics
Base(Base&& rhs); // move semantics
если вы не используете std :: move ()
Derived(Derived&& rhs) : Base(rhs) // wrong: rhs is an lvalue
{
// Derived-specific stuff
}
Правильная версия:
Derived(Derived&& rhs) : Base(std::move(rhs)) // good, calls Base(Base&& rhs)
{
// Derived-specific stuff
}
Также
- создание ссылки lvalue на lvalue - ОК
- создание ссылки на rvalue для rvalue - ОК
- создание константы lvalue для ссылки на rvalue - ОК
- создание ссылки lvalue на rvalue - ОШИБКА компиляции