Когда использовать std :: forward для пересылки аргументов?
C ++ 0x показывает пример использования std::forward
:
template void foo(T&& arg) { bar(std::forward(arg)); }
Когда выгодно использовать std::forward
, всегда?
Кроме того, требуется использовать &&
в объявлении параметров, действительно ли это во всех случаях? Я думал, что вам нужно передать временные функции функции, если функция была объявлена с помощью &&
в ней, поэтому можно вызвать foo с любым параметром?
- Определить, является ли тип указателем в функции шаблона
- Можно ли написать шаблон для проверки существования функции?
- Каковы различия между Generics в C # и Java ... и шаблонами в C ++?
- Как использовать class в Java?
- Если я хочу специализироваться только на одном методе в шаблоне, как мне это сделать?
Наконец, если у меня есть вызов функции, например:
template void doSomething(Params... args) { doSomethingElse(args...); }
Должен ли я использовать это вместо этого:
template void doSomething(Params&&... args) { doSomethingElse(std::forward(args)...); }
Кроме того, если использовать параметры дважды в функции, то есть пересылка на две функции одновременно, целесообразно ли использовать std::forward
? Не будет std::forward
преобразовать одну и ту же вещь в временную дважды, перемещая память и делая ее недействительной для второго использования? Будет ли код в порядке:
template void doSomething(Params&&... args) { doSomethingElse(std::forward(args)...); doSomethingWeird(std::forward(args)...); }
Я немного смущен std::forward
, и я бы с удовольствием воспользовался некоторыми прояснениями.
- Есть ли ошибка компилятора, представленная моей реализацией свойства is_complete?
- Шаблонный набор - вызов функции для каждого элемента
- Как я могу проверить, является ли тип экземпляром данного шаблона classа?
- gcc может скомпилировать вариационный шаблон, в то время как clang не может
- Как убедиться, что параметр шаблона является подтипом требуемого типа?
- Что означает шаблон ?
- Почему эта двусмысленность здесь?
- Как вызвать функцию члена шаблона?
Используйте его, как ваш первый пример:
template void f(T && x) { g(std::forward(x)); } template void f(Args && ...args) { g(std::forward(args)...); }
Это из-за правил сбрасывания ссылок : если T = U&
, то T&& = U&
, но если T = U&&
, то T&& = U&&
, поэтому вы всегда получаете правильный тип внутри тела функции. Наконец, вам нужно перевернуть, чтобы включить lvalue- x
(потому что теперь он имеет имя!) Обратно в ссылку rvalue, если она была изначально.
Вы не должны пересылать что-то более одного раза, потому что это обычно не имеет смысла: пересылка означает, что вы потенциально перемещаете аргумент до последнего вызывающего абонента, и как только он перемещается, он исчез, поэтому вы не можете его использовать снова (так, как вы, вероятно, хотели).