最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++11中的{}初始化,initializer_list,右值引用全解

 更新時間:2026年06月24日 09:22:19   作者:望舒329  
本文詳細(xì)解析了C++1初始化初始化方式及列表初始化,介紹了C++中左值與右值引用的概念及其用途,并探討了移動語義、引用折疊和完美轉(zhuǎn)發(fā)等特性,強(qiáng)調(diào)了這些特性在提高代碼效率上的重要作用,感興趣的朋友一起看看吧

1.C++11中的{}

1.C++11以后想統(tǒng)?初始化?式,試圖實現(xiàn)?切對象皆可?{}初始化,{}初始化也叫做列表初始化。

2.內(nèi)置類型?持,?定義類型也?持,?定義類型本質(zhì)是類型轉(zhuǎn)換,中間會產(chǎn)?臨時對象,最后優(yōu)化 了以后變成直接構(gòu)造。 

3.{}初始化的過程中,可以省略掉=。

4.C++11列表初始化的本意是想實現(xiàn)?個?統(tǒng)?的初始化?式,其次他在有些場景下帶來的不少便 利,如容器push/inset多參數(shù)構(gòu)造的對象時,{}初始化會很?便

#include<iostream>
#include<vector>
using namespace std;
struct Point
{
	int _x;
	int _y;
};
class Date
{
public:
	Date(int month, int day, int year)
		:_month(month),
		_year(year),
		_day(day)
	{};
private:
	int _month=0;
	int _year=0;
	int _day=0;
};
int main()
{
	int x{ 2 };
	Date d1{ 2,3,4 };
	const Date& d2 = { 2024, 7, 25 };
	Point p1{ 1, 2 };
	return 0;
}

2.initializer_list

initializer_list是一個方便容器初始化創(chuàng)造的類,這個類的本質(zhì)是底層開?個數(shù)組,將數(shù)據(jù)拷? 過來,std::initializer_list內(nèi)部有兩個指針分別指向數(shù)組的開始和結(jié)束。支持迭代器遍歷,同時容器支持initializer_list構(gòu)造也就支持多個參數(shù)的構(gòu)造STL中的容器?持任意多個值構(gòu)成的 {x1,x2,x3...} 進(jìn)?初始化,就是通過 std::initializer_list的構(gòu)造函數(shù)?持的。

int main()
{
	std::initializer_list<int> mylist;
	mylist = { 10, 20, 30 };
	cout << sizeof(mylist) << endl;
    // 這?begin和end返回的值initializer_list對象中存的兩個指針 
    // 這兩個指針的值跟i的地址跟接近,說明數(shù)組存在棧上 
	cout << mylist.begin() << " " << mylist.end() << endl;
	vector<int> v1(mylist);
	vector<int> v2 = { 1,2,3,4,5 };
	vector<int> v3({ 1,2,3,4 });
	return 0;
}

3.右值引用和移動語義

3.1 左值和右值

左值是?個表?數(shù)據(jù)的表達(dá)式(如變量名或解引?的指針),?般是有持久狀態(tài),存儲在內(nèi)存中,我 們可以獲取它的地址,左值可以出現(xiàn)賦值符號的左邊,也可以出現(xiàn)在賦值符號右邊。定義時const 修飾符后的左值,不能給他賦值,但是可以取它的地址。

右值也是?個表?數(shù)據(jù)的表達(dá)式,要么是字?值常量、要么是表達(dá)式求值過程中創(chuàng)建的臨時對象 等,右值可以出現(xiàn)在賦值符號的右邊,但是不能出現(xiàn)出現(xiàn)在賦值符號的左邊,右值不能取地址。

值得?提的是,左值的英?簡寫為lvalue,右值的英?簡寫為rvalue。傳統(tǒng)認(rèn)為它們分別是left value、rightvalue的縮寫?,F(xiàn)代C++中,lvalue被解釋為loactorvalue的縮寫,可意為存儲在內(nèi) 存中、有明確存儲地址可以取地址的對象,?rvalue被解釋為readvalue,指的是那些可以提供 數(shù)據(jù)值,但是不可以尋址,例如:臨時變量,字?量常量,存儲于寄存器中的變量等,也就是說左 值和右值的核?區(qū)別就是能否取地址。

3.2 左值引?和右值引?

1.Type& r1 = x; Type&& rr1 = y; 第?個語句就是左值引?,左值引?就是給左值取別 名,第?個就是右值引?,同樣的道理,右值引?就是給右值取別名。

2.左值引?不能直接引?右值,但是const左值引?可以引?右值

3.右值引?不能直接引?左值,但是右值引?可以引?move(左值)

move是一個函數(shù),底層類似于對左值進(jìn)行強(qiáng)轉(zhuǎn):(string&&)s,內(nèi)部具體先不講述

4.需要注意的是變量表達(dá)式都是左值屬性,也就意味著?個右值被右值引?綁定后,右值引?變量變 量表達(dá)式的屬性是左值,底層都是指針實現(xiàn)的,左值右值引用目的都是為了提高效率。

int main()
{
	int* p = new int(0);
	int b = 1;
	const int c = b;
	*p = 10;
	string s("111111");
	s[0] = 'x';
	double x = 1.1, y = 2.2;
	// 左值引?給左值取別名 
	int& r1 = b;
	int*& r2 = p;
	int& r3 = *p;
	string& r4 = s;
	char& r5 = s[0];
	// 右值引?給右值取別名 
	int&& rr1 = 10;
	double&& rr2 = x + y;
	double&& rr3 = fmin(x, y);
	string&& rr4 = string("11111");
	// 左值引?不能直接引?右值,但是const左值引?可以引?右值 
	const int& rx1 = 10;
	const double& rx2 = x + y;
	const double& rx3 = fmin(x, y);
	const string& rx4 = string("11111");
	// 右值引?不能直接引?左值,但是右值引?可以引?move(左值) 
	int&& rrx1 = move(b);
	int*&& rrx2 = move(p);
	int&& rrx3 = move(*p);
	string&& rrx4 = move(s);
	string&& rrx5 = (string&&)s;
	return 0;
}

3.3引?延??命周期

右值引用可以延長臨時對象的生命周期,const 左值引用也可以延長,但是這些對象無法被修改

int main()
{
	string&& s1 = "test";
	const string& s2 = s1 + s1;//cosnt左值引用無法改變
	string&& s3 = s1 + s1;
	s3 += "abg";//右值引用是左值可以改變
	cout << s3;
	return 0;
}

3.4 左值和右值的參數(shù)匹配

C++98中,我們實現(xiàn)?個const左值引?作為參數(shù)的函數(shù),那么實參傳遞左值和右值都可以匹配。 C++11以后,分別重載左值引?、const左值引?、右值引?作為形參的f函數(shù),那么實參是左值會匹配f(左值引?),實參是const左值會匹配f(const 左值引?),實參是右值會匹配f(右值引?),會優(yōu)先匹配最適合的。

3.5 移動構(gòu)造和移動賦值

1.移動構(gòu)造函數(shù)是?種構(gòu)造函數(shù),類似拷?構(gòu)造函數(shù),移動構(gòu)造函數(shù)要求第?個參數(shù)是該類類型的引 ?,但是不同的是要求這個參數(shù)是右值引?,如果還有其他參數(shù),額外的參數(shù)必須有缺省值。

2.移動賦值是?個賦值運(yùn)算符的重載,他跟拷?賦值構(gòu)成函數(shù)重載,類似拷?賦值函數(shù),移動賦值函 數(shù)要求第?個參數(shù)是該類類型的引?,但是不同的是要求這個參數(shù)是右值引?。

3.對于像string/vector這樣的深拷?的類或者包含深拷?的成員變量的類,移動構(gòu)造和移動賦值才有意義,因為移動構(gòu)造和移動賦值的第?個參數(shù)都是右值引?的類型,他的本質(zhì)是要“竊取”引?的右值對象的資源,?不是像拷?構(gòu)造和拷?賦值那樣去拷?資源,從提?效率,直接轉(zhuǎn)移資源,在傳值返回時可以提效。

3.6引用折疊和完美轉(zhuǎn)發(fā)

引用折疊

C++中不能直接定義引?的引?,這樣寫會直接報錯,通過模板或typedef 中的類型操作可以構(gòu)成引?的引?。產(chǎn)生這種情況時C++引入了引用折疊的規(guī)則:右值引用的右值引用是右值引用,其他都是左值引用

// 由于引?折疊限定,f1實例化以后總是?個左值引? 
template<class T>
void f1(T& x)
{}
// 由于引?折疊限定,f2實例化后可以是左值引?,也可以是右值引? 
template<class T>
void f2(T&& x)
{}
int main()
{
	typedef int& lref;
	typedef int&& rref;
	int n = 0;
	lref& r1 = n; // r1 的類型是 int& 
	lref&& r2 = n; // r2 的類型是 int& 
	rref& r3 = n; // r3 的類型是 int& 
	rref&& r4 = 1; // r4 的類型是 int&&
	// 沒有折疊->實例化為void f1(int& x) 左值引用的左值引用是左值引用
	f1<int>(n);
	//f1<int>(0); // 報錯 左值引用不能引用臨時對象(右值)
	// 折疊->實例化為void f1(int& x) 
	f1<int&>(n);
	//f1<int&>(0); // 報錯 
	// 折疊->實例化為void f1(int& x) 
	f1<int&&>(n);
	//f1<int&&>(0); // 報錯
	// 折疊->實例化為void f1(const int& x) 
	f1<const int&>(n);
	f1<const int&>(0);//const 左值引用可以引用右值
	// 折疊->實例化為void f1(const int& x) 
	f1<const int&&>(n);
	f1<const int&&>(0);
	// 沒有折疊->實例化為void f2(int&& x) 
	//f2<int>(n); // 報錯 右值引用不能引用左值 
	f2<int>(0);
	// 折疊->實例化為void f2(int& x) 
	f2<int&>(n);
	//f2<int&>(0); // 報錯 
	// 折疊->實例化為void f2(int&& x) 
	//f2<int&&>(n); // 報錯 
	f2<int&&>(0);
	return 0;
}

同時f2也被稱為萬能引用,傳左值是左值引用,傳右值是右值引用

template<class T>
void Function(T&& t)
{
	int a = 0;
	T x = a;
	x++;
	cout << x;
}
int main()
{
	Function(10);//傳右值T被推到為int,int&&是右值引用
	int a = 0;
	Function(a);//傳左值T被推到為int& ,int& &&是int&
	const int b = 8;
	Function(b);// b是左值,推導(dǎo)出T為const int&,引?折疊,模板實例化為void Function(const int& t)
				// 所以Function內(nèi)部會編譯報錯,x不能++ 
	Function(move(b));//b是右值,推到出T為const int,x不能++;
	return 0;
}

完美轉(zhuǎn)發(fā)

Function(T&& t)函數(shù)模板程序中,傳左值實例化以后是左值引?的Function函數(shù),傳右值實例化 以后是右值引?的Function函數(shù)。但是右值引用是左值,如果下一層函數(shù)使用t,t的屬性就會改變,在這樣的情況應(yīng)該使用forward<T> 完美轉(zhuǎn)發(fā)實現(xiàn)

完美轉(zhuǎn)發(fā)forward本質(zhì)是?個函數(shù)模板,他主要還是通過引?折疊的?式實現(xiàn),下??例中傳遞給 Function的實參是右值,T被推導(dǎo)為int,沒有折疊,forward內(nèi)部t被強(qiáng)轉(zhuǎn)為右值引?返回;傳遞給 Function的實參是左值,T被推導(dǎo)為int&,引?折疊為左值引?,forward內(nèi)部t被強(qiáng)轉(zhuǎn)為左值引?返回。

using namespace std;
void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }
void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }
template<class T>
void Function(T&& t)
{
	Fun(t);
}
template<class T>
void Function1(T&& t)
{
	Fun(forward<T>(t));
}
int main()
{
	Function(10);
	Function1(10);
	const int b = 8;
	Function(b);
	Function1(b);
	Function(move(b));
	Function1(move(b));
	return 0;
}

到此這篇關(guān)于C++11中的{}初始化,initializer_list,右值引用全解的文章就介紹到這了,更多相關(guān)C++ {}初始化,initializer_list,右值引用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言用easyx實現(xiàn)消磚塊游戲

    C語言用easyx實現(xiàn)消磚塊游戲

    這篇文章主要為大家詳細(xì)介紹了C語言消磚塊游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C++合并二叉樹的思路與示例代碼

    C++合并二叉樹的思路與示例代碼

    二叉樹大家應(yīng)該都不陌生,但是合并二叉樹呢?這篇文章主要給大家介紹了關(guān)于C++合并二叉樹的相關(guān)資料,文中給出了兩種解決的方法,大家可以根據(jù)需要選擇對應(yīng)的方法,需要的朋友可以參考下
    2021-08-08
  • 在C++中實現(xiàn)高效的數(shù)組原地輪轉(zhuǎn)的方法總結(jié)

    在C++中實現(xiàn)高效的數(shù)組原地輪轉(zhuǎn)的方法總結(jié)

    在 C++ 中,可以通過多種方式實現(xiàn)數(shù)組的輪轉(zhuǎn)操作,以下是幾種常見的實現(xiàn)方法及其對應(yīng)的代碼示例,文中通過代碼示例介紹的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下
    2025-04-04
  • c語言冒泡排序和選擇排序的使用代碼

    c語言冒泡排序和選擇排序的使用代碼

    算法中排序是十分重要的,而每一個學(xué)習(xí)計算機(jī)的都會在初期的時候接觸到這種排序,下面這篇文章主要給大家介紹了關(guān)于c語言冒泡排序和選擇排序使用的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • 一波C語言字符數(shù)組實用技巧集錦

    一波C語言字符數(shù)組實用技巧集錦

    這篇文章主要介紹了一波C語言字符數(shù)組實用技巧集錦,包括許多字符的轉(zhuǎn)換與提取等基本操作示例,需要的朋友可以參考下
    2016-04-04
  • C++?如何使用棧求解中綴、后綴表達(dá)式的值

    C++?如何使用棧求解中綴、后綴表達(dá)式的值

    這篇文章主要介紹了C++?使用棧求解中綴、后綴表達(dá)式的值,本文講解了中綴、后綴表達(dá)式的求值過程以及如何將一個中綴表達(dá)式轉(zhuǎn)換成后綴表達(dá)式,需要的朋友可以參考下
    2022-10-10
  • C語言實現(xiàn)動態(tài)順序表的實現(xiàn)代碼

    C語言實現(xiàn)動態(tài)順序表的實現(xiàn)代碼

    這篇文章主要介紹了C語言實現(xiàn)動態(tài)順序表的實現(xiàn)代碼的相關(guān)資料,動態(tài)順序表在內(nèi)存中開辟一塊空間,可以隨我們數(shù)據(jù)數(shù)量的增多來擴(kuò)容,需要的朋友可以參考下
    2017-08-08
  • C++變量,常量,數(shù)組和字符串詳解

    C++變量,常量,數(shù)組和字符串詳解

    這篇文章主要介紹了C++變量,常量,數(shù)組和字符串,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-10-10
  • C++實現(xiàn)圖書管理系統(tǒng)課程設(shè)計(面向?qū)ο?

    C++實現(xiàn)圖書管理系統(tǒng)課程設(shè)計(面向?qū)ο?

    這篇文章主要為大家詳細(xì)介紹了C++實現(xiàn)圖書管理系統(tǒng)課程設(shè)計,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C語言超詳細(xì)講解猜數(shù)字游戲的實現(xiàn)

    C語言超詳細(xì)講解猜數(shù)字游戲的實現(xiàn)

    現(xiàn)在很多游戲都有抽獎抽卡的功能,其實這個就類似于猜數(shù)字,生成一個隨機(jī)數(shù),然后你去猜,猜對了就得獎。猜到一定次數(shù)就會保底。要實現(xiàn)猜數(shù)字的小游戲,首先是要讓程序生成隨機(jī)數(shù),這就要用到rand、srand和time這三個函數(shù),其次要了解時間戳
    2022-07-07

最新評論

百色市| 安义县| 锡林浩特市| 兴宁市| 开鲁县| 浮梁县| 阿拉尔市| 禹州市| 青河县| 黄陵县| 和顺县| 徐水县| 新民市| 麦盖提县| 庆城县| 大洼县| 会宁县| 阿尔山市| 新丰县| 西华县| 南召县| 尉犁县| 湖北省| 大城县| 游戏| 松溪县| 抚松县| 湖北省| 同仁县| 玉林市| 梁山县| 广灵县| 上虞市| 图片| 德清县| 新民市| 治县。| 两当县| 翼城县| 松阳县| 南充市|