Skip to content

Way to C++: 5. Forwarding Reference ​

前言 ​

假如有一個函數,可以吃下 Int 和 Char 的 l-value 和 r-value 作為參數

cpp
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 一下,但是當我們嘗試實作時,就會產生疑問:

cpp
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。

cpp
template<typename T>
void CallFoo(T&& val) {
    printf("Call foo!\n");
    foo(val); // 這也有問題
}

他會把 l-value 和 r-value 好好的傳遞成 l-value 和 r-value。Example:

  1. CallFoo(1) : r-value
  2. CallFoo(x) : l-value

但假如只有這樣,仍然是有問題的。因為在 Foo 裡面,直接使用 val 仍然會被視作 l-value 去呼叫 foo 。

std::forward ​

這函數就是為了這種情況誕生的,它可以把 l-value, r-value 送到該有的地方。

cpp
template<typename T>
void CallFoo(T&& val) {
    printf("Call foo!\n");
    foo(std::forward<T>(val));
}

Just observe 👀