c++是一門偉大的語言,永遠給程式設計師最大的設計自由, 未使用的特性從不產生***,新版本永遠完全相容舊版本。 c++11先前被稱作c++0x,即iso/iec 14882:2011,是c++程式語言的乙個標準。
c++98 auto
早在c++98標準中就存在了auto關鍵字,那時的auto用於宣告變數為自動變數,自動變數意為擁有自動的生命期,這是多餘的,因為就算不使用auto宣告,變數依舊擁有自動的生命期:
int a =10 ;//擁有自動生命期
auto int b = 20 ;//擁有自動生命期
static int c = 30 ;//延長了生命期
c++98中的auto多餘且極少使用,c++11已經刪除了這一用法,取而代之的是全新的auto:變數的自動型別推斷。
c++11 auto
auto可以在宣告變數的時候根據變數初始值的型別自動為此變數選擇匹配的型別,類似的關鍵字還有decltype。舉個例子:
auto a = 10;
auto *pa = new auto(a);
auto **rpa = new auto(&a);
cout << typeid(a).name() << endl; //輸出:int
cout << typeid(pa).name() << endl; //輸出:int *
cout << typeid(rpa).name() << endl; //輸出:int **
typeid運算子可以輸出變數的型別。
這種用法就類似於c#中的var關鍵字。auto的自動型別推斷發生在編譯期,所以使用auto並不會造成程式執行時效率的降低。而是否會造成編譯期的時間消耗,我認為是不會的,在未使用auto時,編譯器也需要得知右運算元的型別,再與左運算元的型別進行比較,檢查是否可以發生相應的轉化,是否需要進行隱式型別轉換。
auto的用法
上面舉的這個例子很簡單,在真正程式設計的時候也不建議這樣來使用auto,直接寫出變數的型別更加清晰易懂。下面列舉auto關鍵字的正確用法。
用於代替冗長複雜、變數使用範圍專一的變數宣告
想象一下在沒有auto的時候,我們操作標準庫時經常需要這樣:
#include#includeint main()
}
這樣看**寫**實在煩得很。有人可能會說為何不直接使用using namespace std,這樣**可以短一點。實際上這不是該建議的方法(c++primer對此有相關敘述)。使用auto能簡化**:
#include#includeint main()
}
for迴圈中的i將在編譯時自動推導其型別,而不用我們顯式去定義那長長的一串。
在定義模板函式時,用於宣告依賴模板引數的變數型別
#include #include using namespace std;
templatevoid add(t t, u u)
int main()
若不使用auto變數來宣告s,那這個函式就難定義啦,不到編譯的時候,誰知道x*y的真正型別是什麼呢?
函式返回佔位符
在這種情況下,auto主要與decltype關鍵字配合使用,作為返回值型別後置時的佔位符。此時,關鍵字不表示自動型別檢測,僅僅是表示後置返回值的語法的一部分。
templateauto add(t t, u u) -> decltype(t + u)
auto在這裡的作用也稱為返回值佔位,它只是為函式返回值佔了乙個位置,真正的返回值是後面的decltype(t + u)。為何要將返回值後置呢?如果沒有後置,則函式宣告時為:
templatedecltype((*(t*)0) + (*(u*)0)) add(t t, u u)
此時雖然能實現相同的功能,但是**編寫要醜陋得多。
注意事項
1.auto 變數必須在定義時初始化,這類似於const關鍵字
定義在乙個auto序列的變數必須始終推導成同一型別。例如:
auto a4 = 10, a5 = 20, a6 = 30;//正確
auto b4 = 10, b5 = 20.0, b6 = 'a';//錯誤,沒有推導為同一型別
2.如果初始化表示式是引用,則去除引用語義
int a = 10;
int &b = a;
auto c = b;//c的型別為int而非int&(去除引用)
auto &d = b;//此時c的型別才為int&
c = 100;//a =10;
d = 100;//a =100;
3.如果初始化表示式為const或volatile(或者兩者兼有),則除去const/volatile語義
const int a1 = 10;
auto b1= a1; //b1的型別為int而非const int(去除const)
const auto c1 = a1;//此時c1的型別為const int
b1 = 100;//合法
c1 = 100;//非法
4.如果auto關鍵字帶上&號,則不去除const語意
const int a2 = 10;
auto &b2 = a2;//因為auto帶上&,故不去除const,b2型別為const int
b2 = 10; //非法
這是因為如何去掉了const,則b2為a2的非const引用,通過b2可以改變a2的值,則顯然是不合理的。
5.初始化表示式為陣列時,auto關鍵字推導型別為指標
int a3[3] = ;
auto b3 = a3;
cout << typeid(b3).name() << endl;//輸出int*
6.若表示式為陣列且auto帶上&,則推導型別為陣列型別
int a7[3] = ;
auto & b7 = a7;
cout << typeid(b7).name() << endl;//輸出為int[3]
7.函式或者模板引數不能被宣告為auto
void func(auto a) //錯誤
8.時刻要注意auto並不是乙個真正的型別
auto僅僅是乙個佔位符,它並不是乙個真正的型別,不能使用一些以型別為運算元的操作符,如sizeof或者typeid。
cout << sizeof(auto) << endl;//錯誤
cout << typeid(auto).name() << endl;//錯誤
c 11新特性之auto
在早期版本中,auto關鍵字用來宣告具有自動儲存器的區域性變數,auto關鍵字很少被使用,除了靜態變數之外,其它的變數預設是auto的。因此,在c 11中,刪除了原有的功能,並對其重新設計,增加了auto的型別推導功能。template double add t1 a,t2 b int main i...
c 11新特性(1)之auto
auto這是乙個很小的語法,就是讓編譯器自動推測物件的型別,需要注意的是一定要保證編譯器可以推測出此物件的型別,不能出現模稜兩可的情況。不過話又說回來對於c 來說,時刻清除物件的型別,恐怕是讀懂程式的基礎,auto只是一種偷懶的做法,平時自己寫 的時候,不建議使用,能看懂別人寫的 就行。下面附乙個小...
C 11新特性 auto關鍵字
熟悉指令碼語言的人都知道,很多指令碼語言都引入了 型別自動推斷 技術 比如python,可以直接宣告變數,在執行時進行型別檢查。隨著c 11標準的發布,c 語言也引入了型別自動推斷的功能,這就是我們今天要介紹的auto關鍵字。c 是一種強型別語言,宣告變數時必須明確指出其型別。但是,在實踐中,優勢我...