Perfect forwarding — preserving value category (lvalue/rvalue) through forwarding.
1#include <utility>23// Universal reference4template<typename T>5void wrapper(T&& arg) {6 // Forward preserving value category7 func(std::forward<T>(arg));8}910void func(int& x) {11 std::cout << "lvalue\n";12}1314void func(int&& x) {15 std::cout << "rvalue\n";16}1718int main() {19 int x = 10;20 wrapper(x); // lvalue — calls func(int&)21 wrapper(20); // rvalue — calls func(int&&)22 wrapper(std::move(x)); // rvalue — calls func(int&&)23}
How it works:
T&& — universal reference (deduction).std::forward<T> — casts to original type.Use cases: