Way to C++: 5. Forwarding Reference
前言
假如有一個函數,可以吃下 Int 和 Char 的 l-value 和 r-value 作為參數
void foo(int&& a) {
printf("R-Int: %d\n", a);
}
void foo(char&& c) {
printf("R-Char: %c\n", c);
}
void foo(const int& a) {
printf("L-Int: %d\n", a);
}
void foo(const char& c) {
printf("L-Char: %c\n", c);
}
並且,我們希望可以再呼叫這個函數之前先 log 一下,但是當我們嘗試實作時,就會產生疑問:
template<typename T>
void CallFoo(??? val) {
printf("Call foo!\\n");
foo(val);
}
???
到底該怎麼填? val
可以是 r-value ,不可以填 T&
。
Forwarding Reference
為了能夠承接下 l-value 和 r-value ,我們要使用 T&& 做為模板型別。而這就是 Forwarding Reference。
template<typename T>
void CallFoo(T&& val) {
printf("Call foo!\\n");
foo(val); // 這也有問題
}
他會把 l-value 和 r-value 好好的傳遞成 l-value 和 r-value。Example:
CallFoo(1)
: r-valueCallFoo(x)
: l-value
但假如只有這樣,仍然是有問題的。因為在 Foo
裡面,直接使用 val 仍然會被視作 l-value 去呼叫 foo
。
std::forward
這函數就是為了這種情況誕生的,它可以把 l-value, r-value 送到該有的地方。
template<typename T>
void CallFoo(T&& val) {
printf("Call foo!\\n");
foo(std::forward<T>(val));
}