函數模板呼叫時,實參轉換為形參會發生型別退化:引用變值、右值變左值,導致原始實參資訊遺失,即「完美轉發」問題。
#include <utility> // std::forward
// 萬用引用參數:T&& 可綁定左值或右值
template <typename T>
void wrapper(T&& arg) {
// 完美轉發:保留原始值類別
process(std::forward<T>(arg));
}
// 重載版本區分左值/右值
void process(int& x) { std::cout << "lvalue: " << x << std::endl; }
void process(int&& x) { std::cout << "rvalue: " << x << std::endl; }
std::forward<T>(arg):若 T 推導為左值引用(U&),回傳左值;若為非引用(U),回傳右值T&& 實現引用摺疊規則:& + & = &, & + && = &, && + & = &, && + && = &&T 傳給 forward// 工廠函數完美轉發建構參數
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
// 使用
auto p1 = make_unique<std::string>("hello"); // 右值
std::string s = "world";
auto p2 = make_unique<std::string>(s); // 左值
auto p3 = make_unique<std::string>(std::move(s)); // 右值轉換
「萬用引用配合 forward,左值右值全保留」 — 這是現代 C++ 泛型程式設計的核心技巧。