Cpp 11 / 万能引用、引用折叠和完美转发
一、萬能引用
1、英文:Universal Reference? 。
2、誕生的原因
因為 C++ 中存在左值引用和右值引用,導致若想同時實現既可傳入左值又可傳入右值的功能,需要對相同函數進行重載,導致代碼冗余。
3、解決辦法
為了解決上述問題,就誕生了萬能引用,具體用法如下:
template<typename T> void func(T&& param) {; }主要實現方法是依靠 C++ 強大的模板推導能力,在編譯期間確定 param 是左值還是右值。?
4、擴展
&&,在模板形參列表中代表萬能引用,在其他地方就代表右值引用。
5、栗子
#include <iostream>template <typename T> void func(T &¶m) {std::cout << param << std::endl; } int main() {int num = 0;func(num);func(100);return 0; } 0 100?二、引用折疊
1、英文:Reference Collapse 。
2、誕生的原因
模板函數:
template <typename T> void func(T ¶m) {std::cout << param << std::endl; }template <typename T> void func(T &¶m) {std::cout << param << std::endl; }?函數形參由于有左值引用和右值引用之分,傳入函數的數據也有左值引用和右值引用的區分,這就分出了 4 種情況。
但是 C++ 是不能對引用進行引用的,故需要一種方案,判定上述 4 種情況下最終的結果是左值引用還是右值引用。
3、解決辦法
為了解決上述問題,誕生了引用折疊這個概念,也就是判定上述 4 種情況下最終的結果是左值引用還是右值引用的方案,如下:
| 形參 | 傳入數據 | 結果 |
| & | & | & |
| & | && | & |
| && | & | & |
| && | && | && |
?可以發現,形參和傳入數據只要有一個是左值引用,其結果就是左值引用;只有全部都是右值引用的情況下其結果才能是右值引用。
4、注意
引用折疊只能發生在模板函數中,即:編譯期間。
5、栗子
#include <iostream>template <typename T> void func_L(T ¶m) {std::cout << param << std::endl; }template <typename T> void func_R(T &¶m) {std::cout << param << std::endl; }int getvalue() {return 100; } int main() {int num = 0;int &&num_r = getvalue();func_L(num);func_L(num_r);func_R(num);func_R(200);return 0; } 0 100 0 200?三、完美轉發
1、英文:Perfect Forwarding 。
2、誕生的原因
經過上述引用折疊之后,傳之前的數據的引用類型和傳入之后的引用類型可能發生變化,怎么才能保持引用類型呢?如下:
#include <iostream>template <typename T> void func(T ¶m) {std::cout << "左值" << std::endl; } template <typename T> void func(T &¶m) {std::cout << "右值" << std::endl; }template <typename T> void warp(T &¶m) {func(param); }int main() {int num = 0;warp(num);warp(100);return 0; } 左值 左值?3、解決辦法
為了解決上述問題,增加了完美轉發的概念,即:經過轉發之后,數據的引用類型恢復到之前的類型。
4、栗子
#include <iostream>template <typename T> void func(T ¶m) {std::cout << "左值" << std::endl; } template <typename T> void func(T &¶m) {std::cout << "右值" << std::endl; }template <typename T> void warp(T &¶m) {func(std::forward<T>(param)); }int main() {int num = 0;warp(num);warp(100);return 0; } 左值 右值?
(SAW:Game Over!)?
?
總結
以上是生活随笔為你收集整理的Cpp 11 / 万能引用、引用折叠和完美转发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Cpp / Hash 所得字符串转成 H
- 下一篇: 通信 / DHCP 四次握手