C++11新特性中auto 和 decltype 區別和聯繫
C++11新特性中auto 和 decltype 區別和聯繫
一. auto簡介
編程時候常常需要把表達式的值付給變量,需要在聲明變量的時候清楚的知道變量是什麼類型。然而做到這一點並非那麼容易(特別是模板中),有時候根本做不到。為了解決這個問題,C++11新標準就引進了auto型別說明符,用它就能讓編譯器替我們去分析表達式所屬的型別。和原來那些只對應某種特定的型別說明符(例如 int)不同。 auto 讓編譯器透過初始值來進行型別推演。從而得到定義變數的類型,所以說 auto 定義的變數必須有初始值。
//由val_1 和val_2相加的结果可以推断出item的类型 auto item = val_1 + val_2;//item 类型初始化为val_1 + val_2相加后的类型,值为val_1+val_2相加的值。
這裡的 item 的型別是編譯器在編譯的過程中經由val_1和val_2的型別相加後推導出來的。假如是val_1(int) + val_2(double),那麼item的類型就是double.
使用auto也能在一個語句中聲明多個變量,因為一個聲明雨具只能有一個基本類型,所以該雨具只能在一個語句中聲明雨具所有變數的初始基本資料型態都必須是一樣的。這裡一定要區別資料類型和類型修飾符! !
int i = 3; auto a = i,&b = i,*c = &i;//正确: a初始化为i的副本,b初始化为i的引用,c为i的指针. auto sz = 0, pi = 3.14;//错误,两个变量的类型不一样。
編譯器推斷的auto類型有時會跟初始值的類型並不完全一樣,編譯器會適當的改變結果類型使得其更符合初始化規則。
首先,如我們熟悉的,並使用引用其實是使用所引用的對象,特別當引用被用作初始值的時候,真正參與初始化的其實是引用對象的值。此時編譯器以引用對象的型別為auto的型別:
int i = 0 ,&r = i;//定义一个整数i,并且定义r为i的应用. auto a = r; //这里的a为为一个整数,其值跟此时的i一样.
由此可被看出auto會忽略上等,其次,auto一般會忽略且頂層const,但為底層保留使用數值是指向常數的指針時:
int i = 0; const int ci = i, &cr = ci; //ci 为整数常量,cr 为整数常量引用 auto a = ci; // a 为一个整数, 顶层const被忽略 auto b = cr; // b 为一个整数,顶层const被忽略 auto c = &ci; // c 为一个整数指针. auto d = &cr; // d 为一个指向整数常量的指针(对常量对象区地址是那么const会变成底层const)
如果你希望推論auto類型是一個頂層的const,也可以將引用的型別設為auto,此時原來的初始化規則仍然適用(用於引用聲明的const都是底層const):
const auto f = ci;
二. decltype簡介
變數的類型,但卻不想用表達式的值去初始化變數。還有可能是函數的傳回類型為某表達式的值型別。在這些時候auto顯得就無力了,所以C++11又引入了第二種型態說明符decltype,它的作用是選擇並傳回運算元的資料型態。在這個過程中,編譯器只是分析表達式並得到它的類型,卻不進行實際的計算表達式的值。
auto &g = ci; //g是一个整数常量引用,绑定到ci。 auto &h = 42; // 错误:非常量引用的初始值必须为左值。 const auto &j = 42; //正确:常量引用可以绑定到字面值。
在這裡編譯器並非實際呼叫f函數,而是分析f函數的回傳值作為sum的定義型別。
基本上decltype的作用和auto很相似,就不一一列舉了。對於decltype還有一個用途就是在c++11引入的後置回傳型別。
三. decltype 和auto 區別
decltype在處理頂層const和引用的方式與auto有些許不同,如果decltype使用的表達式是一個變量,則decltype )。
decltype(f()) sum = x;// sum的类型就是函数f的返回值类型。
decltype還有一些值得注意的地方,我們先來看看下面這段程式碼:
const int ci = 42, &cj = ci; decltype(ci) x = 0; // x 类型为const int auto z = ci; // z 类型为int decltype(cj) y = x; // y 类型为const int& auto h = cj; // h 类型为int
如果表達式的內容是解引用運算,則decltype將會得到引用型別。正如我們所熟悉的那樣,解引用指針可以得到指針所指對象,而且還可以給這個對象賦值。因此decltype(*p)的結果類型是int&.
decltype和auto上有一個重要的差異是,decltype的結果型態與表現形式有密切關係。有一種情況需要特別注意:對於decltype 所用表達式來說,如果變數名稱加上一對括號,則得到的類型與不加上括號的時候可能不同。如果decltype使用的是一個不加括號的變量,那麼得到的結果就是這個變數的型別。但是如果給這個變數加上一個或多層括號,那麼編譯器會把這個變數當作一個表達式看待,變數是一個可以當作左值的特殊表達式,所以這樣的decltype就會回傳引用型別:
int i = 42, *p = &i, &r = i; decltype(i) x1 = 0; //因为 i 为 int ,所以 x1 为int auto x2 = i; //因为 i 为 int ,所以 x2 为int decltype(r) y1 = i; //因为 r 为 int& ,所以 y1 为int& auto y2 = r; //因为 r 为 int& ,但auto会忽略引用,所以 y2 为int decltype(r + 0) z1 = 0; //因为 r + 0 为 int ,所以 z1 为int, auto z2 = r + 0; //因为 r + 0 为 int ,所以 z2 为int, decltype(*p) h1 = i; //这里 h1 是int&, 原因后面讲 auto h2 = *p; // h2 为 int.
这里再指出一个需要注意的地方就是 = 赋值运算符返回的是左值的引用。换句话意思就是说 decltype(i = b) 返回类型为 i 类型的引用。仔细看下面这段代码:
int main() { int i = 42; decltype(i = 41) x = i; auto y = i; auto& z = i; printf("i x y z 此时为: %d %d %d %d\n", i,x,y,z); i--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); x--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); y--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); z--; printf("i x y z 此时为: %d %d %d %d\n", i, x, y, z); return 0; }
运行结果为:
i x y z 此时为: 42 42 42 42 i x y z 此时为: 41 41 42 41 i x y z 此时为: 40 40 42 40 i x y z 此时为: 40 40 41 40 i x y z 此时为: 39 39 41 39
由上面的代码和运行结果可以看出来,1.decltype(i = 41)中的赋值语句并没有真正的运行。2. decltype(i = 41)返回的其实是int&,也就是说x 其实是 i 的引用。
了解了auto 和 decltype后,以后在使用的过程中一定要分清两者的区别,防止在定义的时候产生const 与非const 以及引用 与非引用 的差别!!
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
更多C++11新特性中auto 和 decltype 区别和联系相关文章请关注PHP中文网!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

C#.NET依然重要,因為它提供了強大的工具和庫,支持多種應用開發。 1)C#結合.NET框架,使開發高效便捷。 2)C#的類型安全和垃圾回收機制增強了其優勢。 3).NET提供跨平台運行環境和豐富的API,提升了開發靈活性。

C#.NETisversatileforbothwebanddesktopdevelopment.1)Forweb,useASP.NETfordynamicapplications.2)Fordesktop,employWindowsFormsorWPFforrichinterfaces.3)UseXamarinforcross-platformdevelopment,enablingcodesharingacrossWindows,macOS,Linux,andmobiledevices.

C#在企業級應用、遊戲開發、移動應用和Web開發中均有廣泛應用。 1)在企業級應用中,C#常用於ASP.NETCore開發WebAPI。 2)在遊戲開發中,C#與Unity引擎結合,實現角色控制等功能。 3)C#支持多態性和異步編程,提高代碼靈活性和應用性能。

c#.netissutableforenterprise-levelapplications withemofrosoftecosystemdueToItsStrongTyping,richlibraries,androbustperraries,androbustperformance.however,itmaynotbeidealfoross-platement forment forment forment forvepentment offependment dovelopment toveloperment toveloperment whenrawspeedsportor whenrawspeedseedpolitical politionalitable,

C#在.NET中的編程過程包括以下步驟:1)編寫C#代碼,2)編譯為中間語言(IL),3)由.NET運行時(CLR)執行。 C#在.NET中的優勢在於其現代化語法、強大的類型系統和與.NET框架的緊密集成,適用於從桌面應用到Web服務的各種開發場景。

C#和.NET通過不斷的更新和優化,適應了新興技術的需求。 1)C#9.0和.NET5引入了記錄類型和性能優化。 2).NETCore增強了雲原生和容器化支持。 3)ASP.NETCore與現代Web技術集成。 4)ML.NET支持機器學習和人工智能。 5)異步編程和最佳實踐提升了性能。

如何將C#.NET應用部署到Azure或AWS?答案是使用AzureAppService和AWSElasticBeanstalk。 1.在Azure上,使用AzureAppService和AzurePipelines自動化部署。 2.在AWS上,使用AmazonElasticBeanstalk和AWSLambda實現部署和無服務器計算。

C#和.NET運行時緊密合作,賦予開發者高效、強大且跨平台的開發能力。 1)C#是一種類型安全且面向對象的編程語言,旨在與.NET框架無縫集成。 2).NET運行時管理C#代碼的執行,提供垃圾回收、類型安全等服務,確保高效和跨平台運行。
