C++11新特性中auto 和 decltype 區別和聯絡

來源:互聯網
上載者:User
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也能在一個語句中聲明多個變數,因為一個聲明雨具只能有一個基礎資料型別 (Elementary Data Type),所以該雨具所有變數的初始基礎資料型別 (Elementary Data Type)都必須是一樣的。在這裡一定要區別資料類型和類型修飾符!!

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,但底層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,需要明確指出:

const auto f = ci;

還可以將引用的類型設為auto,此時原來的初始化規則仍然適用(用於引用聲明的const都是底層const):

auto &g = ci; //g是一個整數常量引用,綁定到ci。auto &h = 42; // 錯誤:非常量引用的初始值必須為左值。const auto &j = 42; //正確:常量引用可以綁定到字面值。

二. decltype簡介

有的時候我們還會遇到這種情況,我們希望從運算式中推斷出要定義變數的類型,但卻不想用運算式的值去初始設定變數。還有可能是函數的傳回型別為某運算式的的實值型別。在這些時候auto顯得就無力了,所以C++11又引入了第二種類型說明符decltype,它的作用是選擇並返回運算元的資料類型。在此過程中,編譯器只是分析運算式並得到它的類型,卻不進行實際的計算運算式的值。

decltype(f()) sum = x;// sum的類型就是函數f的傳回值類型。

在這裡編譯器並不實際調用f函數,而是分析f函數的傳回值作為sum的定義類型。

基本上decltype的作用和auto很相似,就不一一列舉了。對於decltype還有一個用途就是在c++11引入的後置傳回型別。

三. decltype 和 auto 區別

decltype在處理頂層const和引用的方式與auto有些許不同,如果decltype使用的運算式是一個變數,則decltype返回該變數的類型(包括頂層const和引用在內)。

const int ci = 42, &cj = ci;  decltype(ci) x = 0;  // x 類型為const intauto z = ci;     // z 類型為int  decltype(cj) y = x;  // y 類型為const int&auto h = cj;     // h 類型為int

decltype還有一些值得注意的地方,我們先來看看下面這段代碼:

int i = 42, *p = &i, &r = i;  decltype(i) x1 = 0;    //因為 i 為 int ,所以 x1 為intauto 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將得到參考型別。正如我們所熟悉的那樣,解引用指標可以得到指標所指對象,而且還可以給這個對象賦值。因此decltype(*p)的結果類型就是int&.

decltype和auto還有一處重要的區別是,decltype的結果類型與表達形式密切相關。有一種情況需要特別注意:對於decltype 所用運算式來說,如果變數名加上一對括弧,則得到的類型與不加上括弧的時候可能不同。如果decltype使用的是一個不加括弧的變數,那麼得到的結果就是這個變數的類型。但是如果給這個變數加上一個或多層括弧,那麼編譯器會把這個變數當作一個運算式看待,變數是一個可以作為左值的特殊運算式,所以這樣的decltype就會返回參考型別:

int i = 42;  //decltype(i)  int 類型//decltype((i)) 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 42i x y z 此時為: 41 41 42 41i x y z 此時為: 40 40 42 40i x y z 此時為: 40 40 41 40i x y z 此時為: 39 39 41 39

由上面的代碼和運行結果可以看出來,1.decltype(i = 41)中的指派陳述式並沒有真正的運行。2. decltype(i = 41)返回的其實是int&,也就是說x 其實是 i 的引用。

瞭解了auto 和 decltype後,以後在使用的過程中一定要分清兩者的區別,防止在定義的時候產生const 與非const 以及引用 與非引用 的差別!!

感謝閱讀,希望能協助到大家,謝謝大家對本站的支援!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.