Я прочитал все основные вопросы по SO о различных категориях значений, но до сих пор не ясно понимаю разницу между, в данном случае, xvalues и prvalues.
Я знаю, что, как и все glvalues, xvalues может иметь свой динамический тип, отличный от статического, но, например, в случае буквального против std::move
из буквального я не могу найти «настоящие» поведенческие различия (возможно, кроме тех, которые формально основаны на том, что xvalue и что prvalue, например, какой конструктор будет вызываться в MyClass(std::move(5))
; но это не кажется важным в случае литералов, так как их значения не будут использоваться в любом случае.
Какую реальную «выгоду» я могу получить от звонка std::move
на буквальном?
Какую реальную «выгоду» я могу получить от звонка
std::move
на буквальном?
Никто. (Не строковый) литерал — это значение, которое является значением. призвание std::move()
даст вам значение x, но это все еще значение. Нет никакой возможности перегрузить разницу между xvalue и prvalue — вы можете перегрузить только разницу между lvalue и rvalue — так что никакой последующей разницы нет.
Однако, если мы обобщим на вызов std::move
на первый взгляд, есть одно большое преимущество: вы теряете временное продление жизни в тех местах, где это может вам понадобиться. Рассматривать:
SomeContainer foo();
for (auto&& elem : foo()) { ... }
Это отлично работает. Вы можете перебрать значение prvalue таким образом. Однако это не работает вообще:
SomeContainer foo();
for (auto&& elem : std::move(foo())) { ... }
Мы еще иметь значение типа SomeContainer
, но теперь наш временный объект связан с опорным параметром move()
так что выходит за рамки видимости тела for
цикл введен. К сожалению.
Других решений пока нет …