左值右值, 左值引用右值引用,完美轉發

一. 左值和右值

左值: 可以取地址的對象
右值: 不可以取地址的對象

double x=1.0, y = 2.0;
1;				// 字面量, 不可取地址, 是右值
x + y;			// 表達式返回值, 不可取地址, 是右值
max(x, y);		// 傳值返回函數的返回值 (非引用返回)

總結就是: 根據是否可以取地址來區分是左值還是右值

二.左值引用和右值引用

左值引用: 對左值的引用, 給左值起別名, 主要是為了避免對象拷貝.

int a = 1;
int& la = a;

右值引用: 對右值的引用, 給右值起別名, 主要是為了延長對象的生命周期

int&& ra = 10;

注意, 右值引用變量, 其實是左值, 可以對它取地址和賦值

int x = 1, y = 2;
int&& right_ref = x + y;
cout << right_ref << endl;
right_ref = 10;
cout << right_ref << endl;

2.1 左值引用指向右值 和 右值引用指向左值

左值引用可以指向右值, 需要const來修飾, 這一點在方法里很常用, 比如push_back接口, 并且const修是, 所以即使傳進來的是右值, 也沒關系.

void test(const int& a)
{cout << a << endl;
}int main() {int a = 1;int&& ra = move(a);test(a);test(ra);
}

右值引用可以指向左值, 需要std::move(v)

int a = 1;
int&& ra = move(a);
cout << ra << endl;
a = 2;
cout << ra << endl;
ra = 3;
cout << a << endl;

三. 左值引用的意義

傳參返回值時, 避免對象拷貝, 節省了內存, 提搞了效率

class A
{
public:int _a;A(int a) : _a(a) {};// 返回值時, 避免拷貝A& operator +=(const int& i){_a += i;return *this;}
};// 傳參時, 避免拷貝
void test(const A& a)
{cout << a._a << endl;
}int main() {A a(1);test(a);a += 1;test(a);
}

但是在返回值返回左值引用時, 如果返回的是局部變量, 那么除了函數作用域是不行的

class A
{
public:int _a;A(int a) : _a(a) {};A& operator +=(const int& i){A a(_a);// 返回局部變量, 會直接報錯return *a;}
};int main() {A a(1);a += 1;
}

四. 右值引用的意義

將一個對象中的資源移動到另一個對象(資源控制權的轉移)。
拷貝構造: const左值引用
移動構造: 右值引用
移動賦值: const左值引用, 是運算符重載
用例如下

class A
{
public:int _a;A(int a) : _a(a) {cout << "構造函數" << endl;};A(const A& a){cout << "拷貝構造函數" << endl;_a = a._a;}A(A&& a) noexcept{cout << "移動構造函數" << endl;_a = a._a;}A& operator=(const A& a) noexcept{cout << "移動賦值函數" << endl;_a = a._a;return *this;}
};A test()
{A a(1);cout << &a << endl;// 但是現代編譯器中, 這里已經不執行移動構造函數了, 用了更好的優化方式return a;
}int main() {A a = test();cout << &a << endl;A a2 = a;A a3 = std::move(a);A a4(1);a4 = std::move(a3);
}

執行結果
在這里插入圖片描述

五. 完美轉發

5.1 前提知識

函數模板中的&&不表示右值引用, 而表示萬能引用
不完美轉發的例子

void f(int& x)
{cout << "左值引用" << endl;
}void f(const int& x)
{cout << "const 左值引用" << endl;
}void f(int&& x)
{cout << "右值引用" << endl;
}void f(const int&& x)
{cout << "const右值引用" << endl;
}template<typename T>
void test(T&& t)
{f(t);
}int main() {int a = 1;test(a);const int b = 1;test(b);test(1);const int d = 1;test(std::move(d));
}

執行結果和我們猜想的差別很大, 是因為, 右值引用本身是左值, 所以在模板函數中, 我們傳進去的是右值, 但是等到調用f函數的時候, 已經全部是左值了
在這里插入圖片描述

5.2完美轉發

由上面的例子我們可以看到, 是一個不完美轉發, 因為右值失去了它的右值屬性, 于是便提出了完美轉發, 核心方法是
std::forward, 它在傳參過程中, 保留對象原生類型的屬性, 我們稍加修改一下上面的例子

void f(int& x)
{cout << "左值引用" << endl;
}void f(const int& x)
{cout << "const 左值引用" << endl;
}void f(int&& x)
{cout << "右值引用" << endl;
}void f(const int&& x)
{cout << "const右值引用" << endl;
}template<typename T>
void test(T&& t)
{f(std::forward<T>(t));
}int main() {int a = 1;test(a);const int b = 1;test(b);test(1);const int d = 1;test(std::move(d));
}

執行結果和我們預想的一致了
在這里插入圖片描述

總結

右值引用是c++11引入的最重要的新特性之一, 配合著移動語義和完美轉發, 是的c++程序運行更加高效.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39416.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39416.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39416.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

線程池666666

1. 作用 線程池內部維護了多個工作線程&#xff0c;每個工作線程都會去任務隊列中拿取任務并執行&#xff0c;當執行完一個任務后不是馬上銷毀&#xff0c;而是繼續保留執行其它任務。顯然&#xff0c;線程池提高了多線程的復用率&#xff0c;減少了創建和銷毀線程的時間。 2…

git修改已提交的commit注釋

在Git中修改已經提交的commit注釋通常有以下幾種情況和相應的方法&#xff1a; 1. 修改最后一次提交的注釋&#xff08;快速修正&#xff09; 如果你想要修改的是最后一次提交的注釋&#xff0c;可以使用 --amend 選項&#xff1a; git commit --amend這個命令會將你的暫存區…

基于深度學習的光度檢測

基于深度學習的光度檢測&#xff08;Photometric Detection&#xff09;涉及從圖像中檢測和分析光照信息&#xff0c;用于多種應用&#xff0c;如場景理解、照明調節、增強現實&#xff08;AR&#xff09;、圖像增強等。以下是關于這一領域的系統介紹&#xff1a; 1. 任務和目…

JAVA基礎教程DAY1-類與方法及形參實參

首先經過C語言的學習&#xff0c;我們已經學會了基本的編程方法&#xff0c;我們知道C語言是面向過程的編程語言&#xff0c;而JAVA是面向對象的編程語言&#xff0c;所以接下來我們通過對比和舉例來進行JAVA語言的學習 首先我們來講類的概念 類&#xff1a;類是一個模板&…

Ubuntu開通5005端口 記錄

Ubuntu版本&#xff1a;20.04 使用systemctl status firewalld查看防火墻狀態&#xff0c;報錯Unit firewalld.service could not be found 報錯的原因是沒有安裝firewall&#xff0c;安裝命令為sudo apt install firewalld&#xff0c;然后進行安裝 安裝完成后輸入systemctl…

vscode jupyter選擇Python環境時找不到我安裝的Python

在一些情況下&#xff0c;我們需要自己安裝一個Python&#xff0c;在選擇內核是可能找不到指定的Python版本&#xff0c; 再次打開內核選擇頁面就能看到Python環境了 注意先到指定環境下安裝依賴包&#xff1a; ./python3 pip install ipykernel notebook jupyter

人工智能-NLP簡單知識匯總01

人工智能-NLP簡單知識匯總01 1.1自然語言處理的基本概念 自然語言處理難點&#xff1a; 語音歧義句子切分歧義詞義歧義結構歧義代指歧義省略歧義語用歧義 總而言之&#xff1a;&#xff01;&#xff01;語言無處不歧義 1.2自然語言處理的基本范式 1.2.1基于規則的方法 通…

[DataWhale大模型應用開發]學習筆記1-嘗試搭建向量數據庫

1.詞向量 1.定義 詞向量&#xff08;Word Vector&#xff09;是將單詞表示為向量形式的技術&#xff0c;是自然語言處理&#xff08;NLP&#xff09;中的一種常用方法。通過將單詞轉化為向量&#xff0c;計算機能夠更好地理解和處理語言。簡單來說&#xff0c;詞向量就是將單…

Windows系統安裝NVM,實現Node.js多版本管理

目錄 一、前言 二、NVM簡介 三、準備工作 1、卸載Node 2、創建文件夾 四、下載NVM 五、安裝NVM 六、使用NVM 1、NVM常用操作命令 2、查看NVM版本信息 3、查看Node.js版本列表&#xff1b; 4、下載指定版本Node.js 5、使用指定版本Node.js 6、查看已安裝Node.js列…

深度學習賦能數據分析,聯蔚盤云引領業務革新

一、引言 隨著大數據時代的到來&#xff0c;深度學習技術正逐漸成為企業數據分析的新引擎。聯蔚盤云憑借其在深度學習領域的深厚積累&#xff0c;為企業提供高效、精準的數據分析解決方案&#xff0c;助力企業實現業務革新與增長。 二、深度學習與數據分析的完美結合 聯蔚盤…

【區塊鏈+基礎設施】國家健康醫療大數據科創平臺 | FISCO BCOS應用案例

在醫療領域&#xff0c;疾病數據合法合規共享是亟待解決的難題。一方面&#xff0c;當一家醫院對患者實施治療后&#xff0c;若患者轉到其 他醫院就醫&#xff0c;該醫院就無法判斷診療手段是否有效。另一方面&#xff0c;醫療數據屬于個人敏感數據&#xff0c;一旦被泄露或被惡…

一個能讓渲染性能提高100倍的辦法

GPU 光線追蹤是當今的熱門話題&#xff0c;所以讓我們來談談它&#xff01;今天我們將光線追蹤一個單個球體。 使用片段著色器。 是的&#xff0c;我知道。并不特別花哨。你可以在 Shadertoy 上搜索并獲得數百個示例(https://www.shadertoy.com/results?querysphere)。甚至已…

在 Excel 中的單元格內開始一行新文本

若要在工作表單元格中開始一行新的文本或在文本的行或段之間添加間距&#xff0c;請按 AltEnter 插入換行符。 雙擊要插入換行符的單元格。 單擊所選單元格內想換行的位置。 按 AltEnter 插入換行符。

自研直播系統-直播系統實戰

文章目錄 1 流媒體基礎本文教程下載地址1.1 流媒體1.2 流式傳輸方式1.2.1 順序流式傳輸1.2.2 實時流式傳輸 1.3 流媒體傳輸協議1.3.1 rtmp協議1.3.2 HLS協議1.3.3 RTSP協議1.3.4 視頻流的對比 1.4 視頻編碼(codec)1.5 分辨率的規范分辨率簡介&#xff1a;1.5.2 分辨率單位 1.6 …

聊聊etsy平臺,一個年入百萬的項目

聊聊etsy平臺&#xff0c;一個年入百萬的項目 什么是etsy,這是怎樣一個平臺&#xff0c;怎樣盈利的&#xff1f;相信現在大家滿腦子都是這些疑問。 這個平臺也是無意間一個學員提到的&#xff0c;據說他朋友靠這個平臺年賺好幾百萬。苦于門檻太高&#xff0c;他也做不了。今天…

重磅發布|WAIC 2024最新活動日程安排完整發布!

WAIC 2024 將于 7 月在上海世博中心和世博展覽館舉行&#xff0c;論壇時間為 7 月 4 日至 6 日&#xff0c;展覽時間為 7 月 4 日至 7 日。會議涵蓋 AI 倫理治理、大模型、具身智能、投融資、教育人才等重點話題&#xff0c;體現 AI 向善等價值導向&#xff0c;9 位大獎得主和 …

Inscription Alliance的Denim協議發行首個聚合跨鏈銘文BTIA,計劃參與Mint注冊量達15萬

官方消息&#xff0c;由Inscription Alliance自主研發的創新性Denim協議發行首個聚合跨鏈銘文BTIA&#xff0c;并將于2024年7月19日公開Mint。Denim協議旨在解決當下銘文賽道流動性和互通性不足的痛點&#xff0c;基于該協議搭建的Denim Swap可以實現聚合各項協議和各條公鏈的彼…

數據結構常見圖算法

深度優先搜索 時間復雜度 領接矩陣表示 O( n2) 領接表表示 O(n+e) 空間復雜度 O(e) DFS與回溯法類似,一條路徑走到底后需要返回上一步,搜索第二條路徑。在樹的遍歷中,首先一直訪問到最深的節點,然后回溯到它的父節點,遍歷另一條路徑,直到遍歷完所有節點…

代碼隨想錄(回溯)

組合&#xff08;Leetcode77&#xff09; 思路 用遞歸每次遍歷從1-n得數&#xff0c;然后list來記錄是不是組合到k個了&#xff0c;然后這個每次for循環的開始不能和上一個值的開始重復&#xff0c;所以設置個遍歷開始索引startindex class Solution {static List<List<…

榮耀大橫評,睿藍7-450榮耀版卷出來的性價比之王

手握11萬左右預算,如何在市場內選出一輛合適自己的車?榮耀版車型無疑是當下的最佳答案。在眾多榮耀版車型中,比亞迪宋PLUS榮耀版EV520km領先型(后統稱宋PLUS榮耀版)、比亞迪元PLUS榮耀版430km領先型(后統稱元PLUS榮耀版)、比亞迪海豚PLUS榮耀版420km時尚版(后統稱海豚榮耀版)、…