2.2.3 std::forward and Universal References

When && is used in association with a type to be deduced, like in the function below:

template<typename T> 
void foo(T&& arg) 
{ 
  /*  */ 
}

Then it refers neither to an rvalue-reference nor a reference. In this context, it is called a universal reference. Depending on how the function is called then T&& will be either deduced to an rvalue-reference, if the argument is an rvalue, or else the references are collapsed and T&& becomes an lvalue-reference, just like T&.

void bar() 
{ 
  std::string s; 
 
  // calls foo(std::string&) 
  foo(s); 
 
  // calls foo(std::string&&) 
  foo(s + "abc"); 
}

Now how one should pass to another function an argument received as a universal reference? If it is deduced as an rvalue-reference, then std::move() should be used, otherwise it should be passed as is.

PIC <utility>

Fortunately C++11 provides std::forward() to do the check for us:

template<typename T> 
void foo(T&& arg) 
{ 
  // Pass as an rvalue-reference or by address, whichever fits. 
  foobar(std::forward<T>(arg)); 
}