官术网_书友最值得收藏!

1.2 C++11語言特性介紹

筆者寫作本書時主流的算法比賽以及在線OJ平臺均已支持最新的C++11語言標準。從開發者的角度來看,新標準中提供了不少能提高開發效率的新特性。本節選擇了一些在算法比賽中常用特性進行介紹,希望讀者通過練習掌握這些語言特性,提高在比賽中的編碼速度和正確率。本書后文中的題解代碼也有較多使用C++11的案例,請讀者參考。

需要注意的是,如果是使用g++編譯,編譯器需要加命令行參數-std=c++11。如果用Visual Studio,則至少需要2013版本。在各大OJ在線提交時,也要選擇C++11。

1.2.1 類型推導(auto)

如果要使用比較長的類型聲明,最常見的就是STL中的枚舉器(iterator),就要寫得很長,例如:

而在C++11中就可以這么寫:

編譯器遇到auto之后會根據右邊的表達式自動推導出其具體類型。同時也支持引用類型的變量:

1.2.2 空指針值(nullptr)

在之前的C/C++代碼中,如果要表示空指針,一般使用“p=NULL;”,實際上NULL只是一個定義為常整數0的宏,這樣有時候就可能和整數類型混淆。

在C++11中,有專門的用來表示空指針的數據類型:nullptr。nullptr關鍵字代表值類型std::nullptr_t,在語義上可以被理解為空指針。

之前的寫法:

C++11中的寫法:

1.2.3 容器的for循環遍歷

以前去遍歷一個STL中的集合(如vector<int>)時要寫出非常煩瑣的代碼:

到了C++11中,其實可以這么寫:

或者如果要修改容器中的數據:

這個語法和Java中的遍歷方式非常像。其實不僅僅是vector,所有的標準容器,如map、string、deque、list,甚至數組都可以這么遍歷,非常方便。

1.2.4 匿名函數(Lambda)

匿名函數是筆者認為最重要的改進,是函數式編程(Funcitonal Programming Style)風格的基石。簡單地說,就是可以在需要的地方定義函數,而不是提前定義好才能用:

以C++98的STL中for_each(InputIterator first,InputIterator last,Function fn)為例,第3個參數需要一個functor(函數對象)。所謂函數對象,其實是一個類,這個類重載了operator,于是這個對象可以像函數一樣被使用。

以前STL中的很多算法都是需要傳入functor的,寫起來非常麻煩。C++11中,就可以直接用lambda代替。另外,利用C++的lambda函數內部也可以對外圍作用域的變量進行捕捉:

上述代碼中的lambda函數內部要對total變量進行寫操作,所以聲明的[&total]部分對total進行按引用捕捉。

另外,還可以直接像聲明一個變量一樣聲明一個函數:

或者聲明的類型部分也可以直接使用類型推導:

關于lambda的用法,有非常大的想象空間。建議讀者參考以下資料仔細學習:https://msdn.microsoft.com/zh-cn/library/dd293608.aspx。

1.2.5 統一的初始化語法

在C++98中,對于數組可以這樣初始化其內容:

但是對于STL中的容器,就必須一個一個元素進行附加:

在C++11中,可以使用像數組那樣的初始化語法對STL容器進行初始化:

1.2.6 哈希容器

比賽中,經常有用哈希容器存儲數據的需要,而C++98標準的STL中并沒有提供基于hash算法的容器,基于平衡二叉樹實現的map可以起到類似的作用,但是在數據量較大時速度還是不夠快(查詢時間復雜度是O(logn)的),有時就不得不自己手動編寫Hash算法。而在C++11中正式引入了幾個基于Hash算法的容器:unordered_map、unordered_set、unordered_multimap和unordered_multiset。

當不需要元素排序時,可以盡量使用這些容器來獲得更好的查找性能。

其他Hash容器的用法類似。

默認的Hash容器只是提供了內置數據類型的Hash算法,如果是自定義類型,就需要提供自定義的Hash函數。自定義類型可能包含幾種內置類型,可以分別算出其Hash,然后對它們進行組合得到一個新的Hash值,一般直接采用移位加異或(XOR)便可得到基本夠用的哈希值(碰撞不太頻繁)。容器處理碰撞時需判斷兩對象是否相等,所以必須提供判斷相等的方法,建議重載“==”操作符:

主站蜘蛛池模板: 冕宁县| 安丘市| 陇西县| 苏尼特右旗| 美姑县| 麟游县| 和政县| 佛学| 社会| 大同市| 运城市| 锡林郭勒盟| 泗阳县| 巨鹿县| 张家港市| 吉林省| 朝阳县| 商都县| 丰镇市| 麻江县| 盐城市| 伊宁市| 盐津县| 福贡县| 临湘市| 武邑县| 桂东县| 青川县| 固安县| 和平区| 鹿邑县| 东乡族自治县| 咸宁市| 搜索| 山东省| 多伦县| 渑池县| 河西区| 高要市| 周至县| 塘沽区|