Когда использовать аргументы 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 ответ:
использовать его как ваш первый пример:
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, если она была изначально.вы не должны пересылать что-то более одного раза, однако, потому что это обычно это не имеет смысла: переадресация означает, что вы потенциально двигаясь аргумент полностью до последнего вызывающего абонента, и как только он перемещен, он исчез, поэтому вы не можете использовать его снова (так, как вы, вероятно, хотели).