一. auto簡介c++
編程時候經常須要把表達式的值付給變量,須要在聲明變量的時候清楚的知道變量是什麼類型。然而作到這一點並不是那麼容易(特別是模板中),有時候根本作不到。爲了解決這個問題,C++11新標準就引入了auto類型說明符,用它就能讓編譯器替咱們去分析表達式所屬的類型。和原來那些只對應某種特定的類型說明符(例如 int)不一樣。auto 讓編譯器經過初始值來進行類型推演。從而得到定義變量的類型,因此說 auto 定義的變量必須有初始值。編程
[cpp] view plain copy函數
這裏的 item 的類型是編譯器在編譯的過程當中經過val_1和val_2的類型相加後推算出來的。假如是val_1(int) + val_2(double),那麼item的類型就是double..net
使用auto也能在一個語句中聲明多個變量,由於一個聲明雨具只能有一個基本數據類型,因此該雨具全部變量的初始基本數據類型都必須是同樣的。在這裏必定要區別數據類型和類型修飾符!!指針
[cpp] view plain copyc++11
編譯器推斷出來的auto類型有時候會跟初始值的類型並不徹底同樣,編譯器會適當的改變結果類型使得其更符合初始化規則。對象
首先,正如咱們熟知的,使用引用實際上是使用引用的對象,特別當引用被用做初始值的時候,真正參與初始化的實際上是引用對象的值。此時編譯器以引用對象的類型做爲auto的類型:blog
[cpp] view plain copyci
由此能夠看出auto會忽略引用,其次,auto通常會忽略掉頂層const,但底層const會被保留下來,好比當初始值是一個指向常量的指針時:get
[cpp] view plain copy
若是你但願推斷出auto類型是一個頂層的const,須要明確指出:
[cpp] view plain copy
還能夠將引用的類型設爲auto,此時原來的初始化規則仍然適用(用於引用聲明的const都是底層const):
[cpp] view plain copy
二. decltype簡介
有的時候咱們還會遇到這種狀況,咱們但願從表達式中推斷出要定義變量的類型,但卻不想用表達式的值去初始化變量。還有多是函數的返回類型爲某表達式的的值類型。在這些時候auto顯得就無力了,因此C++11又引入了第二種類型說明符decltype,它的做用是選擇並返回操做數的數據類型。在此過程當中,編譯器只是分析表達式並獲得它的類型,卻不進行實際的計算表達式的值。
[cpp] view plain copy
在這裏編譯器並不實際調用f函數,而是分析f函數的返回值做爲sum的定義類型。
基本上decltype的做用和auto很類似,就不一一列舉了。對於decltype還有一個用途就是在c++11引入的後置返回類型。
三. decltype 和 auto 區別
decltype在處理頂層const和引用的方式與auto有些許不一樣,若是decltype使用的表達式是一個變量,則decltype返回該變量的類型(包括頂層const和引用在內)。
[cpp] view plain copy
decltype還有一些值得注意的地方,咱們先來看看下面這段代碼:
[cpp] view plain copy
若是表達式的內容是解引用操做,則decltype將獲得引用類型。正如咱們所熟悉的那樣,解引用指針能夠獲得指針所指對象,並且還能夠給這個對象賦值。所以decltype(*p)的結果類型就是int&.
decltype和auto還有一處重要的區別是,decltype的結果類型與表達形式密切相關。有一種狀況須要特別注意:對於decltype 所用表達式來講,若是變量名加上一對括號,則獲得的類型與不加上括號的時候可能不一樣。若是decltype使用的是一個不加括號的變量,那麼獲得的結果就是這個變量的類型。可是若是給這個變量加上一個或多層括號,那麼編譯器會把這個變量看成一個表達式看待,變量是一個能夠做爲左值的特殊表達式,因此這樣的decltype就會返回引用類型:
[cpp] view plain copy
這裏再指出一個須要注意的地方就是 = 賦值運算符返回的是左值的引用。換句話意思就是說 decltype(i = b) 返回類型爲 i 類型的引用。仔細看下面這段代碼:
[cpp] view plain copy
運行結果爲:
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 以及引用 與非引用 的差異!!