Когда использовать аргументы std::forward to forward?


C++0x показывает пример использования std::forward:

template<class T>
void foo(T&& arg) 
{
  bar(std::forward<T>(arg));
}

когда выгодно использовать std::forward всегда?

кроме того, он требует, чтобы использовать && в объявлении параметров он действителен во всех случаях? Я думал, что вы должны были передать временные функции, если функция была объявлена с && в нем, так что можно вызвать foo с любым параметром?

наконец, если у меня есть вызов функции, такие как этот:

template<int val, typename... Params>
void doSomething(Params... args) {
  doSomethingElse<val, Params...>(args...);
}

должен ли я использовать вместо этого:

template<int val, typename... Params>
void doSomething(Params&&... args) {
  doSomethingElse<val, Params...>(std::forward<Params>(args)...);
}

кроме того, если использовать параметры дважды в функции, т. е. переадресация на две функции одновременно, разумно ли использовать std::forward? Не будет std::forward преобразуйте то же самое во временное дважды, перемещая память и делая ее недействительной для второго использования? Будет ли следующий код в порядке:

template<int val, typename... Params>
void doSomething(Params&&... args) {
  doSomethingElse<val, Params...>(std::forward<Params>(args)...);
  doSomethingWeird<val, Params...>(std::forward<Params>(args)...);
}

Я немного запутался std::forward, и я бы с удовольствием использовал некоторые прояснения.

1 138

1 ответ:

использовать его как ваш первый пример:

template <typename T> void f(T && x)
{
  g(std::forward<T>(x));
}

template <typename ...Args> void f(Args && ...args)
{
  g(std::forward<Args>(args)...);
}

это из-за правила сворачивания ссылок: если T = U&, потом T&& = U&, а если T = U&&, потом T&& = U&&, так что вы всегда в конечном итоге с правильным типом внутри тела функции. Наконец, вам нужно forward в свою очередь, именующее,-обратился x (потому что теперь у него есть имя!) вернуться в ссылку rvalue, если она была изначально.

вы не должны пересылать что-то более одного раза, однако, потому что это обычно это не имеет смысла: переадресация означает, что вы потенциально двигаясь аргумент полностью до последнего вызывающего абонента, и как только он перемещен, он исчез, поэтому вы не можете использовать его снова (так, как вы, вероятно, хотели).