Way to C++: 5. Forwarding Reference

Apr 22, 2020·

1 min read

前言

假如有一個函數,可以吃下 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:

  1. CallFoo(1) : r-value
  2. CallFoo(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));  
}