C 11特性 auto關鍵字

2021-08-29 13:55:17 字數 3075 閱讀 5582

正文

本文的內容已經不新鮮了。關於auto,翻來覆去被人知道的都是這些東西,本文並沒有提出新穎的auto用法。

本人原是痛恨部落格一篇篇都是copy而來缺乏新意的探索,當然,本文不是copy而來,但發布這樣一篇大家皆知的文章心裡甚是惶恐。

本文對auto的內容加以整理,權當是自己的複習筆記了。

回到頂部

早在c++98標準中就存在了auto關鍵字,那時的auto用於宣告變數為自動變數,自動變數意為擁有自動的生命期,這是多餘的,因為就算不使用auto宣告,變數依舊擁有自動的生命期:

int a =10 ;  //擁有自動生命期

auto int b = 20 ;//擁有自動生命期

static int c = 30 ;//延長了生命期

c++98中的auto多餘且極少使用,c++11已經刪除了這一用法,取而代之的是全新的auto:變數的自動型別推斷。

回到頂部

auto可以在宣告變數的時候根據變數初始值的型別自動為此變數選擇匹配的型別,類似的關鍵字還有decltype。舉個例子:

int a = 10;

auto au_a = a;//自動型別推斷,au_a為int型別

cout << typeid(au_a).name() << endl;

typeid運算子可以輸出變數的型別。程式的執行結果輸出了

int

這種用法就類似於c#中的var關鍵字。auto的自動型別推斷發生在編譯期,所以使用auto並不會造成程式執行時效率的降低。而是否會造成編譯期的時間消耗,我認為是不會的,在未使用auto時,編譯器也需要得知右運算元的型別,再與左運算元的型別進行比較,檢查是否可以發生相應的轉化,是否需要進行隱式型別轉換。

回到頂部

上面舉的這個例子很簡單,在真正程式設計的時候也不建議這樣來使用auto,直接寫出變數的型別更加清晰易懂。下面列舉auto關鍵字的正確用法。

想象一下在沒有auto的時候,我們操作標準庫時經常需要這樣:

#include#includeint main()

}

這樣看**寫**實在煩得很。有人可能會說為何不直接使用using namespace std,這樣**可以短一點。實際上這不是該建議的方法(c++primer對此有相關敘述)。使用auto能簡化**:

#include#includeint main()

}

for迴圈中的i將在編譯時自動推導其型別,而不用我們顯式去定義那長長的一串。

template void multiply(_tx x, _ty y)

若不使用auto變數來宣告v,那這個函式就難定義啦,不到編譯的時候,誰知道x*y的真正型別是什麼呢?

template auto multiply(_tx x, _ty y)->decltype(_tx*_ty)

當模板函式的返回值依賴於模板的引數時,我們依舊無法在編譯**前確定模板引數的型別,故也無從知道返回值的型別,這時我們可以使用auto。格式如上所示。

decltype操作符用於查詢表示式的資料型別,也是c++11標準引入的新的運算子,其目的也是解決泛型程式設計中有些型別由模板引數決定,而難以表示它的問題。

auto在這裡的作用也稱為返回值佔位,它只是為函式返回值佔了乙個位置,真正的返回值是後面的decltype(_tx*_ty)。為何要將返回值後置呢?如果沒有後置,則函式宣告時為:

decltype(_tx*_ty)multiply(_tx x, _ty y)
而此時_tx,_ty還沒宣告呢,編譯無法通過。

回到頂部

auto a4 = 10, a5 = 20, a6 = 30;//正確

auto b4 = 10, b5 = 20.0, b6 = 'a';//錯誤,沒有推導為同一型別

使用auto關鍵字做型別自動推導時,依次施加一下規則:

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;

const int a1 = 10;

auto b1= a1; //b1的型別為int而非const int(去除const)

const auto c1 = a1;//此時c1的型別為const int

b1 = 100;//合法

c1 = 100;//非法

const int a2 = 10;

auto &b2 = a2;//因為auto帶上&,故不去除const,b2型別為const int

b2 = 10; //非法

這是因為如何去掉了const,則b2為a2的非const引用,通過b2可以改變a2的值,則顯然是不合理的。

int a3[3] = ;

auto b3 = a3;

cout << typeid(b3).name() << endl;

程式將輸出

int *

int a7[3] = ;

auto & b7 = a7;

cout << typeid(b7).name() << endl;

程式輸出

int [3]

void func(auto a)  //錯誤

cout << sizeof(auto) << endl;//錯誤

cout << typeid(auto).name() << endl;//錯誤

C 11特性 auto關鍵字

本文的內容已經不新鮮了。關於auto,翻來覆去被人知道的都是這些東西,本文並沒有提出新穎的auto用法。本人原是痛恨部落格一篇篇都是copy而來缺乏新意的探索,當然,本文不是copy而來,但發布這樣一篇大家皆知的文章心裡甚是惶恐。本文對auto的內容加以整理,權當是自己的複習筆記了。早在c 98標準...

C 11新特性 auto關鍵字

熟悉指令碼語言的人都知道,很多指令碼語言都引入了 型別自動推斷 技術 比如python,可以直接宣告變數,在執行時進行型別檢查。隨著c 11標準的發布,c 語言也引入了型別自動推斷的功能,這就是我們今天要介紹的auto關鍵字。c 是一種強型別語言,宣告變數時必須明確指出其型別。但是,在實踐中,優勢我...

C 11新特性 auto關鍵字

在c 98標準中就存在著auto關鍵字,c 98標準中auto關鍵字用於自動變數的宣告,但在預設情況下即使不宣告auto,函式內部的變數也是具有自動儲存期的。因此由於使用極少且多餘,在c 11中已刪除這一用法。void fun c 11新標準引入了auto型別說明符,採用它可以讓編譯器幫助我們分析表...