Это не неправильно использовать std::forward
здесь (сам по себе), но это неуместно и, таким образом, вводит в заблуждение (в том смысле, можно сказать, что это является на самом деле не так).
Способ, которым вы произносите «приведение чего-то к ссылке rvalue к его типу», является std::move
. Это только вещь, которая std::move
делает-это static_cast<T&&>
, где вам не нужно указывать T
.
std::forward
- это другой зверь, предназначенный для использования с совершенной пересылкой. Совершенная пересылка происходит только в шаблонах, где возможны ссылки пересылки. Ссылка на пересылку является ссылкой, которая, благодаря специальному правилу на языке, может выводить либо ссылку на lvalue, либо ссылку rvalue. Там вам понадобится std::forward<T>
, чтобы повторно установить соответствующую категорию значений (lvalue или rvalue).
Игрушка пример:
void print(int &)
{
std::cout << "Lvalue\n";
}
void print(int &&)
{
std::cout << "Rvalue\n";
}
template <class T>
void perfectForwarder(T &&v)
{
print(std::forward<T>(v));
}
int main()
{
int i;
perfectForwarder(i);
perfectForwarder(std::move(i));
perfectForwarder(42);
}
Выходной сигнал будет:
именующее
Rvalue
RValue
[Live]
«Литой ссылка на rvalue reference «не является« идеальной отправкой ». Это * движение *. –
Совершенная переадресация - это комбинация специального правила вывода аргумента шаблона и свертывания ссылок. – Simple
Также: совершенная пересылка включает в себя «универсальные ссылки», и у вас нет универсальной ссылки; у вас есть ссылка rvalue. 'std :: move' здесь достаточно. – Simple