Но почему C++ не позволяет привязывать объекты lvalue к значениям rvalue?
Предполагая, что вы имеете в виду "Почему не C++ позволяет связывание RValue ссылки на Lvalue объектов": он делает. Это просто не автоматическое, поэтому вы должны использовать std::move
, чтобы сделать его явным.
Почему? Потому что в противном случае вызов безобидной функции может неожиданно уничтожить то, что вы не ожидали его:
Class object(much,state,many,members,wow);
looks_safe_to_me(object);
// oh no, it destructively copied my object!
VS.
Class object(much,state,many,members,wow);
obviously_destructive(std::move(object));
// same result, but now the destruction is explicit and expected
Записка о деструктивном копировании: почему я говорю деструктивно и уничтожение выше, я не имею в виду, что деструктор объекта заканчивает свою жизнь: просто его внутреннее состояние было перемещено в новый экземпляр. Это по-прежнему действительный объект, но он больше не имеет того же дорогостоящего состояния, которым он пользовался.
Замечание по терминологии: давайте посмотрим, если мы можем прояснить неточное использование именующее, Rvalue и т.д. выше.
Цитируя cppreference для потомков:
lvalue является
выражение, которое имеет идентичность и не могут быть перемещены из.
Таким образом, нет такого понятия, как объект Lvalue, но есть объект, который локально по имени (или называют) с помощью Lvalue выражения
rvalue является
в выражение, которое является либо значением prvalue, либо значением x. Это можно переместить с. Он может иметь или не иметь идентичности.
prvalue (чистый Rvalue) примерно выражение со ссылкой на не-имени временного объект: мы не можем преобразовать наше выражение именующего к одному из этого IIUC.
xvalue (истекающее значение)
выражение, которое имеет идентичности и может быть перемещен из.
, который явно включает в себя результат std::move
Так что на самом деле происходит:
- объект существует
- объект идентифицируется локально с помощью Lvalue выражения, из которого нельзя перенести (чтобы защитить нас от неожиданных побочных эффектов)
std::move
дает выражение xvalue (который может быть перемещен с) со ссылкой на тот же объект как-значение выражения
- это означает, что объекты, такие как переменные (которые называются по-значение выражения) не может быть неявно перемещается из, и должен вместо этого явно переместился через явное выражение xvalue, такое как
std::move
.
- анонимные временные конструкции, вероятно, уже ссылается prvalue выражений, и могут быть перемещены неявно
Вы спрашиваете, почему у вас нет 'void foo (vector & bar) {} foo (создайте вектор temp здесь);'? – NathanOliver
Знаете ли вы 'std :: move'? – Jarod42