Forwarding references (also called universal references) use the syntax T&& where T is a deduced template parameter, allowing a function to accept both lvalues and rvalues and preserve their value category. With function template argument deduction and reference collapsing rules, T&& binds to both lvalue and rvalue arguments.
Use forwarding references with std::forward to write generic functions that preserve argument categories and avoid unnecessary copies.
This example shows forwarding references accepting both lvalues and rvalues with their original categories preserved.
// compile: g++ -std=c++17 -o forward forward.cpp // run: ./forward // description: forwarding references accept and preserve lvalue/rvalue distinction #include <iostream> #include <utility> class Widget { public: Widget() { std::cout << "Widget constructed\n"; } Widget(const Widget&) { std::cout << "Widget copied\n"; } Widget(Widget&&) { std::cout << "Widget moved\n"; } }; template <typename T> void process(T&& arg) { std::cout << "Received "; Widget w = std::forward<T>(arg); // preserves lvalue/rvalue } int main() { Widget w; process(w); // lvalue: calls copy process(Widget()); // rvalue: calls move return 0; }