日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

C++拾趣——C++11的语法糖auto

發布時間:2023/11/27 生活经验 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++拾趣——C++11的语法糖auto 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? C++是一種強類型的語言,比如變量a,如果聲明它是整型,則之后只能將它作為整型來用。這和其他弱類型的語言有很大的區別,比如python中,我們可以讓a在第一行是個整型,第三行是一個字符串。(轉載請指明出于breaksoftware的csdn博客)

a = 3
print a
a = "3"
print a

? ? ? ? C++代碼在聲明一個變量時就已經明確指定了它的類型。這樣在編譯器給它分配內存時,就知道分配出什么多大的空間。從這個角度來說,C++的語法是站在編譯器實現的角度設計的。然而隨著編程技術的普及,大家都希望代碼寫出來是給人看的,而不是給機器看的。但是在C++代碼的一些場景下,有一定基礎的程序員都可以通過右值推導出左值變量類型時,編譯器還是要求寫明類型,這無疑加重了程序員的負擔。比如下面的代碼

std::vector<int> vec_int;
……
std::vector<int>::iterator iter = vec_int.begin();

? ? ? ? 如果不看變量iter的類型聲明,我們也可以通過vector的begin()函數返回值類型推導出變量的類型。這樣的推導編譯器也完全可以完成。但是在C++11之前的標準中,我們也只能這種笨拙的方式去聲明。因為老的標準沒要求編譯器完成這樣的工作,而且即使各大編譯器廠商“超前”的完成了,也沒有一種統一的途徑可以表達出來。

? ? ? ? 于是在C++11的標準中引入了auto關鍵字,它讓上述類型推導通過統一的標準表達出來。我們可以使用auto去聲明一個變量,但是這并不意味著C++增加了一個auto類型——一個可以表示任意類型的類型。因為強類型特性是不會變的,變的只是編譯器,它變的更加高級——推導出確定的類型。這兒特別需要指出的是:auto關鍵字并不是在預編譯過程中被替換成確定類型的。大家可以開啟VS2017的“生成預編譯文件”選項來驗證這點。

std::vector<int> vec_int;
……
auto iter = vec_int.begin();

? ? ? ? 上述代碼中auto便將std::vector<int>::iterator替換了,這在一定程度上降低了程序員的負擔。

? ? ? ? 在C++11標準推出之前,我們可以使用別名來減少負擔。比如會在一個共有的頭文件中做如下定義:

typedef std::vector<int> VecInt;
typedef VecInt::iterator VecIntIter;
typedef VecInt::const_iterator VecIntCIter;

? ? ? ? 然后在代碼中使用上述別名

VecInt vec_int;
……
VecIntIter = vec_int.begin();

? ? ? ? 當然這不失為一種方法,但是這就要求每定義一個容器,都要別名它相應的迭代器。auto的出現幫我們省掉了這些繁瑣且意義不大的書寫。

? ? ? ? auto是個非常好的設計,但是也不可毫無原則的濫用。

? ? ? ? 作為C++標準,要求auto變量在聲明時要被初始化。該初始化操作其實就是指定了其真實類型。一般我們可以使用表達式來初始化一個變量,也可以使用字面值、字面量、常量或者一個明確類型的變量。不管我們使用哪種方式,都希望auto的推導不會產生“歧義”。比如

auto i = 0x01;

? ? ? ? 在VS2017中,我們將其類型打印出來(typeid(i).name())是int。那可能會問,為什么不是unsigned int,long等呢?現在我們換個字面值(8個f)

auto i = 0xffffffff;

? ? ? ? 此時,編譯器就會認為類型為unsigned int。我們再修改字面值(15個f,1一個0)

auto i = 0x0fffffffffffffff;

? ? ? ? 編譯器推導出的類型是__int64。我們再將類型改成(16個f)

auto i = 0xffffffffffffffff;

? ? ? ? 編譯器推導出的類型是unsigned __int64。

? ? ? ? 可以見得,在使用字面值或者字面量初始化auto變量時往往會產生“誤解”。所以一旦我們自己對推導產生疑問時,最好使用明確的類型來定義變量。

? ? ? ? 其次,不要寄希望于編譯器可以通過構造函數隱式轉換推導類型。比如下面的初始化方式,我們可能會認為變量類型是std::string。

auto i = "which type?";

? ? ? ? 但是真實的推導類型是char const *。為什么呢?因為當我們使用

std::string i = "which type?"; 

? ? ? ? 賦值符將會觸發basic_string類構造函數隱式轉換(《C++拾趣——類構造函數的隱式轉換》)

	basic_string(_In_z_ const _Elem * const _Ptr): _Mybase(){	// construct from [_Ptr, <null>)_Tidy_init();assign(_Ptr);}

? ? ? ? 這是由于左值已經指定類型才會發生的。所以如果使用auto定義一個字面量,其類型是char const *。鑒于理解這樣的過程需要掌握一定的C++基礎知識,所以我也不建議在這個場景下使用auto去定義變量。

? ? ? ? 綜上所述,除了在模板中必要的地方使用auto外,其他地方都需要可以從右值一眼看出類型,否則就會產生理解上的歧義或者困擾。

總結

以上是生活随笔為你收集整理的C++拾趣——C++11的语法糖auto的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。