可變參數模板、右值引用帶來的移動語義完美轉發、lambda表達式的理解

可變參數模板

可變參數模板對參數進行了高度泛化,可以表示任意數目、任意類型的參數:
語法為:在class或者typename后面帶上省略號。

Template<class ... T>
void func(T ... args)
{//
}

T:模板參數包,args叫做函數參數包
省略號作用:
1、聲明一個包含0到任意個模板參數的參數包
2、在模板定義的右邊,可以將參數包展開一個個獨立的參數
c++11可以使用遞歸函數的方式展開參數包,獲得可變參數的每個值。不過這個需要提供一個參數包展開函數和一個遞歸終止函數。
參數Args…在展開的過程中會遞歸調用自己,每調用一次,參數包中的參數就會少一個,直到所有參數都展開為止。

右值引用

1、臨時對象的深拷貝

一個帶有堆內存的類,必須提供一個深拷貝的拷貝函數。因為默認的拷貝構造函數是淺拷貝,會發生指針懸掛問題(兩個對象的兩個指針指向同一塊內存,當函數作用結束后,兩個對象分別調用析構函數,錯誤地將一塊內存區析構兩次)。
提供深拷貝地構造函數可以保證正確,但是會造成額外地性能損耗。
在這里插入圖片描述
GetA函數會返回臨時變量,然后通過這個臨時變量拷貝構造一個新的對象a,臨時變量在拷貝構造完成之后就銷毀了。如果這個堆內存很大地話,拷貝構造的代價很大。也就是說每次產生臨時變量都會造成額外地性能損失。

2、移動構造函數解決問題

A(A&& a) :m_ptr(a.m_ptr){a.m_ptr = nullptr;cout << "move construct" << endl;}

move construct這個構造函數是移動構造函數,它的參數是一個右值引用類型A&&。
它僅僅是將指針的所有者轉移到了另一個對象上,同時將參數對象a的指針置空。也就是說,這里僅僅做了淺拷貝,從而避免了臨時變量的深拷貝問題。

為什么能夠匹配到這個構造函數呢?
這個構造函數只能夠接受右值參數,而函數的返回值就是右值,所以就會匹配到這個構造函數。A&&看作臨時值的標識。

對于臨時值我們僅僅需要做淺拷貝即可,無需再做深拷貝,從而解決了臨時變量拷貝構造產生的性能損失問題。這就是移動語義

3、左值借助移動語義優化性能

我們可以使用std::move將左值轉換為右值引用。
move是將對象資源的所有權從一個對象轉移到另一個對象,只是轉移,沒有內存的拷貝,這就是所謂的move語義。
通常這樣使用:
使用move將左值轉換成右值引用。應用移動語義,調用移動構造函數。
我們需要記住:
如果一個對象內部有較大的內存或者動態數組,就很有必要寫move語義的拷貝構造函數和賦值函數,避免無所謂的深拷貝,以提高性能

左值引用和右值引用本質作用都是減少拷貝提高效率。
右值引用可以彌補左值引用不足的地方,右值引用做參數和做返回值減少拷貝的本質是利用了移動構造和移動賦值。
左值引用:
做參數: void func(T x) -> void func(T& x) 減少了傳參過程中的拷貝
做返回值: T func() -> T& func() 減少返回過程中的寶貝(返回對象除了作用域不存在了就不能使用傳引用了)
右值引用:
做參數: void func(T&& x) : 使func內部不再將x拷貝構造到容器空間上,而是采用移動構造
做返回值:利用移動構造減少拷貝。

4、完美轉發

右值引用會在第二次之后的參數傳遞過程中右值屬性丟失,在下一層調用中會識別成左值。
C++11引入完美轉發的概念,完美轉發是指在函數模板中,完全依照模板的參數的類型,將參數傳遞給函數模板中調用的另外一個函數

#include<iostream>
using namespace std;
void Fun(int& x)
{cout << "左值引用" << endl;
}
void Fun(int&& x)
{cout << "右值引用" << endl;
}template<typename T>
void PerfectForward(T&& t) 
{Fun(std::forward<T>(t));
}int main()
{//右值引用PerfectForward(10);int a;//左值引用PerfectForward(a);//右值引用PerfectForward(std::move(a));return 0;
}

在這里插入圖片描述

lambda表達式

lambda表達式定義了一個匿名函數,并且可以捕獲一定范圍內的變量,定義如下:
[capture] (params)mutable->return_type{statement}

[capture] :捕獲列表,捕獲上下文變量以供lambda使用。編譯器根據[]符號來判斷接下來的代碼是否是lambda函數。
(params):參數列表,與普通函數的參數列表一致,如果不需要傳遞參數,可以連同括號一起省略
mutable:修飾符,默認情況下lambda函數總是一個const函數,mutable可以取消其常量性。使用該修飾符時,參數列表不可省略
return_type:返回值類型
{statement}:函數體,內容與普通函數一樣,除了可以使用參數之外,還可以使用所捕獲的變量。

lambda表達式與普通函數最大的不同就是它可以通過捕獲列表訪問一些上下文的數據。

[var] : 表示以 值傳遞方式 捕獲 變量var
[=] : 表示以 值傳遞方式 捕獲 所有父作用域的變量(包括this)
[&var] : 表示以 引用傳遞方式 捕獲 變量var
[&] : 表示以 引用傳遞方式 捕獲 所有父作用域的變量(包括this)
[this] : 表示以 值傳遞方式 捕獲當前的this指針

lambda的類型被定義為“閉包”的類,通常用于stl庫中。在某些場景下用于簡化仿函數的使用,同時lambda作為局部函數,也會提高復雜代碼的開發速度。可以在函數內部重用代碼,不需要費心設計接口。
下面是示例代碼:

#include<iostream>
using namespace std;int main()
{int a = 0, b = 1;//實現a+b的lambda表達式auto add1 = [](int x, int y)->int {return x + y;};cout << add1(a, b) << endl;auto add2 = [a, b]()->int {return a + b;};cout << add2() << endl;cout << a << " " << b << endl;//實現a和b的交換auto swap1 = [](int& x, int& y){int tmp = x;x = y;y = tmp;};swap1(a, b);cout << "swap1() " << a << " " << b << endl;auto swap2 = [&a, &b]()mutable{int tmp = a;a = b;b = tmp;};swap2();cout << "swap2() "<< a << " " << b << endl;return 0;
}

在這里插入圖片描述

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

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

相關文章

BI-SqlServer

一.概述 SqlServer數據倉庫ETL組件 IntegrationServiceOLAP組件 AnalysisService報表 ReportingServiceMDX(查多維數據集用的)和DMX(查挖掘模型用的)。二.商業智能-Analysis Services 項目 構建挖掘模型1構建挖掘模型2構建挖掘模型3三.商業智能-SqlServerAnalysis-Asp.net WebS…

python 子圖大小_Python | 圖的大小

python 子圖大小In some cases, the automatic figure size generated by the matplotlib.pyplot is not visually good or there could be some non-acceptable ratio in the figure. So, rather than allowing a pyplot to decide the figure size, we can manually define t…

《設計模式整理》

目錄常見設計模式如何保證單例模式只有一個實例單例模式中的懶漢與餓漢模式OOP設計模式的五項原則單例模式中的懶漢加載&#xff0c;如果并發訪問該怎么做常見設計模式 單例模式&#xff1a; 單例模式主要解決了一個全局使用的類頻繁的創建和銷毀的問題。 單例模式下確保某一個…

JSON學習資料整理

1.什么是JSON JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基于JavaScript的一個子集。 JSON采用完全獨立于語言的文本格式&#xff0c;但是也使用了類似于C語言家族的習慣&#xff08;包括C, C, C#, Java, JavaScript, Perl, Python等&#xff09;。這些…

OSI七層模型及其數據的封裝和解封過程

OSI(Open System Interconnection)參考模型把網絡分為七層: 1.物理層(Physical Layer) 物理層主要傳輸原始的比特流,集線器(Hub)是本層的典型設備; 2.數據鏈路層(Data Link Layer) 數據鏈路層負責在兩個相鄰節點間無差錯的傳送以幀為單位的數據,本層的典型設備是交換機(Switch)…

rss聚合模式案例_RSS的完整形式是什么?

rss聚合模式案例RSS&#xff1a;真正簡單的聯合 (RSS: Really Simple Syndication) RSS is an abbreviation of Really Simple Syndication. It is also called Rich Site Summary. It is quality attainment for the syndication of collection of web content and used to di…

《MySQL——38道查詢練習(無連接查詢)》

目錄一、準備數據1、創建數據庫2、創建學生表3、創建教師表4、創建課程表5、創建成績表6、添加數據二、查詢練習1、查詢 student 表的所有行2、查詢 student 表中的 name、sex 和 class 字段的所有行3、查詢 teacher 表中不重復的 department 列4、查詢 score 表中成績在60-80之…

工作經常使用的SQL整理,實戰篇(一)

工作經常使用的SQL整理&#xff0c;實戰篇&#xff08;一&#xff09; 原文:工作經常使用的SQL整理&#xff0c;實戰篇&#xff08;一&#xff09;工作經常使用的SQL整理&#xff0c;實戰篇&#xff0c;地址一覽&#xff1a; 工作經常使用的SQL整理&#xff0c;實戰篇&#xff…

XPth和XSLT的一些簡單用法

&#xff08;目的在于讓大家知道有這個東西的存在&#xff09; XPath:即XML Path語言(Xpath)表達式使用路徑表示法(像在URL中使用一樣)來為XML文檔的各部分尋址&#xff01; 關于XPath如何使用了&#xff0c;我們來看看&#xff01;當然這里面的代碼只是入門&#xff0c;更深層…

isc dhcp_ISC的完整形式是什么?

isc dhcpISC&#xff1a;印度學校證書 (ISC: Indian School Certificate) ISC is an abbreviation of the Indian School Certificate. It alludes to the 12th class examination or higher secondary examination conducted by the Council for the Indian School Certificat…

《MySQL——連接查詢》

內連接&#xff1a; inner join 或者 join 外連接 1、左連接 left join 或 left outer join 2、右連接 right join 或 right outer join 3、完全外連接 full join 或 full outer join 圖示理解 全連接 創建person表和card表 CREATE DATABASE testJoin;CREATE TABLE person (…

win7下 apache2.2 +php5.4 環境搭建

這篇文章很好 沒法復制 把鏈接粘貼來http://www.360doc.com/content/13/0506/13/11495619_283349585.shtml# 現在能復制了&#xff1a; 把任何一篇你要復制、卻不讓復制的文章收藏入收藏夾(直接CtrlD,確定) 2在收藏夾中&#xff0c;右擊剛才收藏的那個網址&#xff0c;點屬性 3…

HDU_1533 Going Home(最優匹配) 解題報告

轉載請注明出自cxb:http://blog.csdn.net/cxb569262726 題目鏈接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid1533 說實話&#xff0c;這個題目剛開始還真看不出是完備匹配下的最大權匹配&#xff08;當然&#xff0c;這個也可以用網絡流做。&#xff08;應該是添加…

c#中 uint_C#中的uint關鍵字

c#中 uintC&#xff03;uint關鍵字 (C# uint keyword) In C#, uint is a keyword which is used to declare a variable that can store an integral type of value (unsigned integer) the range of 0 to 4,294,967,295. uint keyword is an alias of System.UInt32. 在C&…

《MySQL——事務》

目錄事務的必要性MySQL中如何控制事務手動開啟事務事務的四大特征事務的四大特征事務開啟方式事務手動提交與手動回滾事務的隔離性臟讀現象不可重復讀現象幻讀現象串行化一些補充使用長事務的弊病commit work and chain的語法是做什么用的?怎么查詢各個表中的長事務&#xff1…

運行在TQ2440開發板上以及X86平臺上的linux內核編譯

一、運行在TQ2440開發板上的linux內核編譯 1、獲取源碼并解壓 直接使用天嵌移植好的“linux-2.6.30.4_20100531.tar.bz2”源碼包。 解壓&#xff08;天嵌默認解壓到/opt/EmbedSky/linux-2.6.30.4/中&#xff09; tar xvjf linux-2.6.30.4_20100531.tar.bz2 -C / 2、獲取默認配置…

ArcCatalog ArcMap打不開

原來是因為&#xff1a; 連接了電信的無線網卡 關掉即可 啟動ArcCatalog之后再開啟無線網卡 沒問題&#xff01;轉載于:https://www.cnblogs.com/ccjcjc/archive/2012/08/21/2649867.html

Python熊貓– GroupBy

Python熊貓– GroupBy (Python Pandas – GroupBy) GroupBy method can be used to work on group rows of data together and call aggregate functions. It allows to group together rows based off of a column and perform an aggregate function on them. GroupBy方法可用…

MySQL索引底層原理理解以及常見問題總結

目錄二叉查找樹為索引紅黑樹為索引B樹作為索引B樹作為索引MyISAM存儲引擎索引實現InnoDB存儲引擎索引實現常見問題聚集索引與非聚集索引InnoDB基于主鍵索引和普通索引的查詢有什么區別&#xff1f;InnoDB主鍵索引為何是整型的自增主鍵何時使用業務字段作為主鍵呢&#xff1f;哈…

Spring之HibernateTemplate 和HibernateDaoSupport

spring提供訪問數據庫的有三種方式&#xff1a; HibernateDaoSupport HibernateTemplate&#xff08;推薦使用&#xff09; jdbcTemplate(我們一般不用&#xff09; 類所在包&#xff1a; HibernateTemplate&#xff1a;org.springframework.orm.hibernate3.HibernateTemplate …