В каких сценариях назначение из std :: forward предпочтительнее, чем из std :: move? Зачем? - PullRequest
0 голосов
/ 26 января 2019

Узнав о std::exchange на cppreference.com , я наткнулся на его «возможную реализацию», которая приведена ниже.

  template<class T, class U = T>
  T exchange(T& obj, U&& new_value)
  {
      T old_value = std::move(obj);
      obj = std::forward<U>(new_value);
      return old_value;
  }

Было немного странно видеть obj = std::forward в операторе присваивания вместо std::move, что, я думаю, будет иметь тот же эффект.

Насколько я понимаю, std::move эквивалентен static_cast типу ссылки rvalue (но более выразителен) и всегда возвращает значение xvalue, тогда как std::forward возвращает тот же тип значения, которому оно было передано.

Мой вопрос: почему std:forward используется в приведенном выше фрагменте?и есть ли простое правило, чтобы решить, когда это лучший выбор?

1 Ответ

0 голосов
/ 26 января 2019

То, что есть назначение, не имеет значения. Что отличается от хода вперед, так это то, какой аргумент они принимают при использовании внутри вашей функции:

  • Аргумент forward является ссылочным параметром переадресации вашей функции.
  • Аргумент move является ссылочным параметром rvalue вашей функции (или, в более общем смысле, всего, что вы знаете, не имеет никаких псевдонимов).

Если у вас exchange с lvalue, вы не хотите, чтобы это было перемещено из *

Например, рассмотрим:

std::vector<int> a, b;

f(std::exchange(a, b));

Это фактически вызывает f(a), но также выполняет a = b;. не выполняет a = std::move(b); b по-прежнему можно использовать в первоначальном виде!

См. Также этого ответа моего, а также много других связанных ответов, таких как Что такое std :: move () и когда его следует использовать? , В чем разница между std :: move и std :: forward и ссылками в них.

...