When to use std::forward to forward arguments?

Use it like your first example:

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

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

That's because of the reference collapsing rules: If T = U&, then T&& = U&, but if T = U&&, then T&& = U&&, so you always end up with the correct type inside the function body. Finally, you need forward to turn the lvalue-turned x (because it has a name now!) back into an rvalue reference if it was one initially.

You should not forward something more than once however, because that usually does not make sense: Forwarding means that you're potentially moving the argument all the way through to the final caller, and once it's moved it's gone, so you cannot then use it again (in the way you probably meant to).


Kerrek's answer is very useful, but it doesn't completely answer the question from the title:

When to use std::forward to forward arguments?

In order to answer it, we should first introduce a notion of universal references. Scott Meyers gave this name and nowadays they are often called forwarding references. Basically, when you see something like this:

template<typename T>
void f(T&& param);

bear in mind that param is not an rvalue reference (as one may be tempted to conclude), but a universal reference*. Universal references are characterized by a very restricted form (just T&&, without const or similar qualifiers) and by type deduction - the type T will be deduced when f is invoked. In a nutshell, universal references correspond to rvalue references if they’re initialized with rvalues, and to lvalue references if they’re initialized with lvalues.

Now it's relatively easy to answer the original question - apply std::forward to:

  • a universal reference the last time it’s used in the function
  • a universal reference being returned from functions that return by value

An example for the first case:

template<typename T>
void foo(T&& prop) {
    other.set(prop); // use prop, but don't modify it because we still need it
    bar(std::forward<T>(prop)); // final use -> std::forward
}

In the code above, we don't want prop to have some unknown value after other.set(..) has finished, so no forwarding happens here. However, when calling bar we forward prop as we are done with it and bar can do whatever it wants with it (e.g. move it).

An example for the second case:

template<typename T>
Widget transform(T&& prop) {
   prop.transform();
   return std::forward<T>(prop);
}

This function template should move prop into the return value if it's an rvalue and copy it if it's an lvalue. In case that we omitted std::forward at the end, we would always create a copy, which is more expensive when prop happens to be an rvalue.

*to be fully precise, a universal reference is a concept of taking an rvalue reference to a cv-unqualified template parameter.