程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++11新特性中auto 和 decltype 區別和聯絡

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

編輯:關於C++

C++11新特性中auto 和 decltype 區別和聯絡。本站提示廣大學習愛好者:(C++11新特性中auto 和 decltype 區別和聯絡)文章只能為提供參考,不一定能成為您想要的結果。以下是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,但底層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 int 
auto 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 為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將失掉援用類型。正如我們所熟習的那樣,解援用指針可以失掉指針所指對象,而且還可以給這個對象賦值。因而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 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 以及援用 與非援用 的差異!!

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved