2011年,C++國際標準委員會公佈了C++11標準,這是C++98發佈後13年來第一次重大修正。C++11引入了大量非常有用的特性,使代碼更直觀、簡潔、安全、方便,使C++更加接近java、python這一類的高級語言。
1.nullptr
nullptr的出現是爲了替代NULL。
傳統C++中會把NULL和0視爲同一種東西,儘管有些編譯器把NULL處理爲((void*)0),但是在處理重載函數時就會發生混亂。
void func(int);
void func(char *);
如果你使用的編譯器把NULL定義爲0,那麼此時func(NULL)將會去調用func(int),這可能直接導致程序運行出錯。
爲了解決這個問題,C++11引入了nullptr,專門用來區分NULL、0。因此,給指針賦初值的時候,請使用nullptr。
int *p=nullptr;
2.類型推導
auto
過去,使用stl時會產生大量的冗餘代碼,但卻不能刪減,不僅影響效率,還特別難閱讀。你可能寫過這樣的代碼
std::map<int,std::string>::const_iterator it=m.find(1);
但是現在,你可以這樣寫
auto it=m.find(1);
編譯器會自動推導出正確的類型
auto a=1; // int
auto b=1.1; // double
auto c="abc"; // const char*
auto d={1,2}; // std::initializer_list<int>
值得注意的是,auto是編譯期推導,即在編譯時編譯器推導出正確的類型,將auto自動替換成對應的類型,所以當auto與模板結合時就會產生一些問題
template<typename T,typename U>
auto add(T a,U b)
{
return a+b;
}
這樣寫編譯器會直接報錯,因爲在編譯期,編譯器無法推導出返回值的類型,也就不能替換auto。解決辦法在介紹decltype時將會提到。
注意:auto不能用於函數傳參,不能用於推導數組類型。
decltype
decltype關鍵字是爲了解決auto關鍵字只能對變量進行類型推導的缺陷而出現的,它的用法和sizeof很相似。
當我們需要計算表達式的類型時,decltype就顯得格外重要。
auto a=1;
auto b=1.1;
decltype(a+b) c;
剛剛在介紹auto的時候,有提到auto與模板結合的一些缺陷,這裏使用decltype就能解決剛剛的問題。
template<typename T,typename U>
auto add(T a,U b) -> decltype(a+b)
{
return a+b;
}
C++11引入的這種新的寫法叫做返回類型後置。C++14使得普通函數具有自動推導功能,因此,這樣的寫法也變得合法了。
template<typename T,typename U>
auto add(T a,U b)
{
return a+b;
}
3.區間迭代
基於範圍的for循環
在C++98/03的規範中,如果你使用stl的迭代器迭代,那將會是一件很麻煩的事。
for(std::vector<int>::iterator i = arr.begin(); i != arr.end(); ++i)
{
std::cout << *i << std::endl;
}
有了C++11新特性以後,你可以這樣寫
for(auto &i : arr) // 使用了引用
{
std::cout << i << std::endl;
}
當然,不止stl的模板類可以這樣寫,原本基礎的數組也可以這樣使用。
C++11引入的基於範圍的迭代寫法,使我們能夠寫出像python一樣簡單的代碼。