C++11新特性:自動類型推斷和類型擷取

來源:互聯網
上載者:User

標籤:blog   http   使用   io   strong   ar   art   cti   

聲明:本文是在Alex Allain的文章http://www.cprogramming.com/c++11/c++11-auto-decltype-return-value-after-function.html的基礎上寫成的。

加入了很多個人的理解,不是翻譯。

 

轉載請註明出處 http://blog.csdn.net/srzhz/article/details/7934483

 

自動類型推斷

當編譯器能夠在一個變數的聲明時候就推斷出它的類型,那麼你就能夠用auto關鍵字來作為他們的類型:

 

[cpp] view plaincopy 
  1. auto x = 1;  


編譯器當然知道x是integer類型的。所以你就不用int了。接觸過泛型程式設計或者API編程的人大概可以猜出自動類型推斷是做什麼用的了:幫你省去大量冗長的型別宣告語句。

 

比如下面這個例子:

在原來的C++中,你要想使用vector的迭代器得這麼寫:

[cpp] view plaincopy 
  1. vector<int> vec;  
  2. vector<int>::iterator itr = vec.iterator();  

看起來就很不爽。現在你可以這麼寫了:

 

 

[cpp] view plaincopy 
  1. vector<int> vec;  
  2. auto itr = vec.iterator();  

果斷簡潔多了吧。假如說自動類型推斷只有這樣的用法的話那未免也太naive了。在很多情況下它還能提供更深層次的便利。

 

比如說有這樣的代碼:

 

[cpp] view plaincopy 
  1. template <typename BuiltType, typename Builder>  
  2. void  
  3. makeAndProcessObject (const Builder& builder)  
  4. {  
  5.     BuiltType val = builder.makeObject();  
  6.     // do stuff with val  
  7. }  

這個函數的功能是要使用builder的makeObject產生的執行個體來進行某些操作。但是現在引入了泛型程式設計。builder的類型不同,那麼makeObject返回的類型也不同,那麼我們這裡就得引入兩個泛型。看起來很複雜是吧,所以這裡就可以使用自動類型推斷來簡化操作:

[cpp] view plaincopy 
  1. template <typename Builder>  
  2. void  
  3. makeAndProcessObject (const Builder& builder)  
  4. {  
  5.     auto val = builder.makeObject();  
  6.     // do stuff with val  
  7. }  


因為在得之builder的類型之後,編譯器就已經能知道makeObject的傳回值類型了。所以我們能夠讓編譯器自動去推斷val的類型。這樣一來就省去了一個泛型。

 

你以為自動類型推斷只有這樣的用法?那也太naive了。C++11還允許對函數的傳回值進行類型推斷

 

新的傳回值文法和類型擷取(Decltype)語句 在原來,我們聲明一個函數都是這樣的: [cpp] view plaincopy 
  1. int temp(int a, double b);  

前面那個int是函數的傳回值類型,temp是函數名,int a, double b是參數列表。

現在你可以將函數傳回值類型移到到參數列表之後來定義:

 

[cpp] view plaincopy 
  1. auto temp(int a, double b) -> int;  


後置傳回值類型可以有很多用處。比如有下列的類定義:

 

 

[cpp] view plaincopy 
  1. class Person  
  2. {  
  3. public:  
  4.     enum PersonType { ADULT, CHILD, SENIOR };  
  5.     void setPersonType (PersonType person_type);  
  6.     PersonType getPersonType ();  
  7. private:  
  8.     PersonType _person_type;  
  9. };  


那麼在定義getPersonType函數的時候我們得這麼寫:

 

 

[cpp] view plaincopy 
  1. Person::PersonType Person::getPersonType ()  
  2. {  
  3.     return _person_type;  
  4. }  


因為函數所在的類Person是聲明在函數傳回值之後的,所以在寫傳回值的時候編譯器並不知道這個函數是在哪個類裡面。由於PersonTYpe是Person類的內部聲明的枚舉,所以在看到PersonType的時候,編譯器是找不到這個類型的。所以你就得在PersonTYpe前面加上Person::,告訴編譯器這個類型是屬於Person的。這看起來有點麻煩是吧。當你使用新的傳回值文法的時候呢就可以這麼寫:

 

 

[cpp] view plaincopy 
  1. auto Person::getPersonType () -> PersonType  
  2. {  
  3.     return _person_type;  
  4. }  


因為這次編譯器看到傳回值類型PersonType的時候已經知道這個函數屬於類Person。所以它會到Person類中去找到這個枚舉類型。

 

 

當然上述應用只能說是一個奇技淫巧而已。並沒有幫我們多大的忙(代碼甚至都沒有變短)。所以還得引入C++11的另一個功能。

 

類型擷取(Decltype) 既然編譯器能夠推斷一個變數的類型,那麼我們在代碼中就應該能顯示地獲得一個變數的類型資訊。所以C++介紹了另一個功能:decltype。(實在是不知道這個詞該怎麼翻譯,姑且稱之為類型擷取)。  [cpp] view plaincopy 
  1. int x = 3;  
  2. decltype(x) y = x; // same thing as auto y = x;  

上述代碼就使用了類型擷取功能。和函數傳回值後置文法結合起來,可以有如下應用: [cpp] view plaincopy 
  1. template <typename Builder>  
  2. auto  
  3. makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )  
  4. {  
  5.     auto val = builder.makeObject();  
  6.     // do stuff with val  
  7.     return val;  
  8. }  

前面的例子中這個函數的傳回值是void,所以不需要為傳回值引入泛型。如果傳回值是makeObject的傳回值的話,那麼這個函數就得引入兩個泛型。現在又了類型擷取功能,我們就能在傳回值中自動推斷makeObject的類型了。所以decltype確實為我們提供了很大的便利。 這個功能非常重要,在很多時候,尤其是引入了泛型程式設計的時候,你可能記不住一個變數的類型或者類型太過複雜以至於寫不出來。你就要靈活使用decltype來擷取這個變數的類型。

自動類型推斷在Lambda運算式(匿名函數)中的作用

請參考http://blog.csdn.net/srzhz/article/details/7934652

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.