總述
C++中有一個(gè)關(guān)鍵字,它不進(jìn)行顯式聲明,而進(jìn)行隱式推導(dǎo),auto可以在聲明變量時(shí)根據(jù)變量初始值的類(lèi)型自動(dòng)為此變量選擇匹配的類(lèi)型。C++語(yǔ)言類(lèi)似的關(guān)鍵字還有decltype。
如何評(píng)價(jià) C++ 11 auto 關(guān)鍵字?既然auto關(guān)鍵字可以用來(lái)做類(lèi)型推斷,使得C++在使用auto時(shí)更像是在用動(dòng)態(tài)類(lèi)型語(yǔ)言。
既然auto能幫我們偷很多懶,那平時(shí)寫(xiě)C++還有必要像之前一樣顯式聲明類(lèi)型嗎?最佳實(shí)踐是如何,應(yīng)當(dāng)徹底改變之前的C++習(xí)慣盡可能大量地使用auto,還是在什么樣的特定的情形下才使用auto?
知乎問(wèn)答
知乎上有這么一條問(wèn)題很有意思,大家對(duì)于auto使用有很多的討論,接下來(lái)我就一點(diǎn)點(diǎn)解開(kāi)auto的神秘面紗,讓大家來(lái)進(jìn)行評(píng)判auto。
作者:良知猶存
轉(zhuǎn)載授權(quán)以及圍觀:歡迎添加微信公眾號(hào):Conscience_Remains
先上一段小代碼:
auto f = 3.14;? //double
auto s("hello");? //const char*
auto z = new auto(9);? //int *
從上面可以看到,我們聲明不需要定義顯性的類(lèi)型,只需要用auto定義進(jìn)行自動(dòng)推導(dǎo)即可。
? ? 編程時(shí)經(jīng)常需要把表達(dá)式的值賦給變量,這就要求聲明變量的時(shí)候,我們可以清楚的知道表達(dá)式的類(lèi)型。然而很多時(shí)候名字空間、模板成為類(lèi)型的一部分,導(dǎo)致了程序員在復(fù)雜類(lèi)型的初始化聲明中如履薄冰,所以C++11中引入了auto類(lèi)型說(shuō)明符,用它就可以讓編譯器替我們分析表達(dá)式所屬的類(lèi)型。
簡(jiǎn)潔之道:
舉一個(gè)經(jīng)常使用的容器的iterator的例子:
#include?<string>??
#include <vector>?
void test(std::vector<std::string>&vs)?
{?
? ? std::vector<std::string>::iterator i=vs.begin();?
????for(;i<vs.end();i++)??{?}?
}??
用std::vector<std::string>::iterator定義變量i,在c++中是一個(gè)安全可靠的方法,但是名字也是很長(zhǎng),如果用auto的話(huà),代碼會(huì)簡(jiǎn)潔很多。如下:???????
#include <string>
#include <vector>
void test(std::vector<std::string>&vs)
{
??for(??auto?i=vs.begin();;i<vs.end();i++){
??}
}
誤區(qū)之所:
雖然auto可以自動(dòng)推導(dǎo)類(lèi)型,但是定義的規(guī)則我們還需要注意。
auto i=0,*p=& i; //正確
auto?y;?//錯(cuò)誤,auto定義的變量必須有初始值
auto sz=0,pi=3.14;//錯(cuò)誤,sz和pi的類(lèi)型不一樣
c++11引入了auto類(lèi)型說(shuō)明符,auto讓編譯器通過(guò)初始值來(lái)推算變量的類(lèi)型,所以auto定義的變量必須有初始值。 詳細(xì)解釋一下:
? ? 這里的y,我們使用auto關(guān)鍵字來(lái)聲明,但是不立即對(duì)其進(jìn)行定義,此時(shí)編譯器則會(huì)報(bào)錯(cuò)。這跟通過(guò)其他關(guān)鍵字(除去引用類(lèi)型的關(guān)鍵字)先聲明后定義的變量的使用規(guī)則是不同的。auto聲明的變量必須被初始化,以使編譯器能夠從其初始化表達(dá)式中推導(dǎo)出其類(lèi)型。這個(gè)意義上,auto并非一種類(lèi)型聲明,而是一個(gè)類(lèi)型聲明時(shí)的“占位符”,編譯器在便已是親會(huì)將suto替代為變量實(shí)際的類(lèi)型。
? ? 使用auto也能在一條語(yǔ)句中聲明多個(gè)變量,因?yàn)橐粭l聲明語(yǔ)句只能有一個(gè)基本數(shù)據(jù)類(lèi)型,所以該語(yǔ)句中所有變量的初始基本數(shù)據(jù)類(lèi)型都必須一樣。
但是,上面這么簡(jiǎn)單的變量聲明類(lèi)型,不建議用auto關(guān)鍵字,而是應(yīng)更清晰地直接寫(xiě)出其類(lèi)型。
? ? 因?yàn)閍uto關(guān)鍵字更適用于類(lèi)型冗長(zhǎng)復(fù)雜、變量使用范圍專(zhuān)一時(shí),使程序更清晰易讀。例如上面的簡(jiǎn)潔之道中的例子那樣復(fù)雜的表達(dá)。
使用之途:
1.范圍for循環(huán)中用auto
for?(auto?&?i?:?list){//對(duì)于list中的數(shù)據(jù)來(lái)說(shuō),i是一個(gè)引用,for里面的賦值語(yǔ)句將會(huì)改變list中數(shù)據(jù)
? }
? for (auto? i : list)
? }
2.保存lambda表達(dá)式類(lèi)型的變量聲明:
auto ptr = [](double x){return x*x;};//類(lèi)型為std::function<double(double)>函數(shù)對(duì)象
3.函數(shù)的返回類(lèi)型(auto在C++14可以作為函數(shù)返回類(lèi)型)
template<class T,class U>
auto?fun(T x,U y)
{
? return x*y;
}
這就是我分享的auto關(guān)鍵詞,如果大家有什么更好的思路,歡迎分享交流哈。