С++ Проброс rvalue при помощи std::forward

Возвращает rvalue-ссылку своего аргумента arg, если arg является rvalue-ссылкой. Если аргумент arg является простой lvalue-ссылкой, то функция возвращает arg без изменения его типа.

lvalue (1)
template <class T> T&& forward (typename remove_reference<T>::type& arg) noexcept;
rvalue (2)
template <class T> T&& forward (typename remove_reference<T>::type&& arg) noexcept;

Подробнее: std::forward C++11

std::forward - вспомогательная функция, которая позволяет выполнить идеальную передачу аргументов, принимаемых в качестве rvalue-ссылок.

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


// forward example
#include <utility>      // std::forward
#include <iostream>     // std::cout

// function with lvalue and rvalue reference overloads:
void overloaded (const int& x) {std::cout << "[lvalue]\n";}
void overloaded (int&& x) {std::cout << "[rvalue]\n";}

// function template taking rvalue reference to deduced type:
template <class T> void fn (T&& x) {
  overloaded (x);                   // always an lvalue
  overloaded (std::forward<T>(x));  // rvalue if argument is rvalue
}

int main () {
  int a;
  std::cout << "calling fn with lvalue: ";
  fn (a);

  std::cout << "calling fn with rvalue: ";
  fn (0);

  return 0;
}

Сквозной проброс аргументов во внутреннюю функцию:

#include <iostream>
#include <utility>

using namespace std;

// Функция которая принимает конкретные аргументы
void inner(double a, char b, int c, const string & d)
{
    cout << "a = " << a << endl
         << "b = " << b << endl
         << "c = " << c << endl
         << "d = " << d << endl;
}

// Функция обертка
template<class ... Args> 
void wrapper(Args && ... args)
{
    inner(forward<Args>(args) ... );
}

int main(int argc, char* argv[])
{
    wrapper(123.5, 'w', 777, "Hello World");
    return 0;
}

По теме: Идеальная передача и универсальные ссылки в C++