std::array
看到這個容器的時候肯定會出現(xiàn)這樣的問題:
為什么要引入 std::array 而不是直接使用 std::vector?
已經有了傳統(tǒng)數(shù)組,為什么要用 std::array?
先回答第一個問題,與 std::vector 不同,std::array 對象的大小是固定的,如果容器大小是固定的,那么可以優(yōu)先考慮使用 std::array 容器。另外由于 std::vector 是自動擴容的,當存入大量的數(shù)據(jù)后,并且對容器進行了刪除操作, 容器并不會自動歸還被刪除元素相應的內存,這時候就需要手動運行 shrink_to_fit() 釋放這部分內存。
std::vector<int> v; std::cout << "size:" << v.size() << std::endl; // 輸出 0 std::cout << "capacity:" << v.capacity() << std::endl; // 輸出 0
// 如下可看出 std::vector 的存儲是自動管理的,按需自動擴張 // 但是如果空間不足,需要重新分配更多內存,而重分配內存通常是性能上有開銷的操作 v.push_back(1); v.push_back(2); v.push_back(3); std::cout << "size:" << v.size() << std::endl; // 輸出 3 std::cout << "capacity:" << v.capacity() << std::endl; // 輸出 4
// 這里的自動擴張邏輯與 Golang 的 slice 很像 v.push_back(4); v.push_back(5); std::cout << "size:" << v.size() << std::endl; // 輸出 5 std::cout << "capacity:" << v.capacity() << std::endl; // 輸出 8
// 如下可看出容器雖然清空了元素,但是被清空元素的內存并沒有歸還 v.clear(); std::cout << "size:" << v.size() << std::endl; // 輸出 0 std::cout << "capacity:" << v.capacity() << std::endl; // 輸出 8
// 額外內存可通過 shrink_to_fit() 調用返回給系統(tǒng) v.shrink_to_fit(); std::cout << "size:" << v.size() << std::endl; // 輸出 0 std::cout << "capacity:" << v.capacity() << std::endl; // 輸出 0
|
而第二個問題就更加簡單,使用 std::array 能夠讓代碼變得更加“現(xiàn)代化”,而且封裝了一些操作函數(shù),比如獲取數(shù)組大小以及檢查是否非空,同時還能夠友好的使用標準庫中的容器算法,比如 std::sort。
使用 std::array 很簡單,只需指定其類型和大小即可:
std::array<int, 4> arr = {1, 2, 3, 4};
arr.empty(); // 檢查容器是否為空 arr.size(); // 返回容納的元素數(shù)
// 迭代器支持 for (auto &i : arr) { // ... }
// 用 lambda 表達式排序 std::sort(arr.begin(), arr.end(), [](int a, int b) { return b < a; });
// 數(shù)組大小參數(shù)必須是常量表達式 constexpr int len = 4; std::array<int, len> arr = {1, 2, 3, 4};
// 非法,不同于 C 風格數(shù)組,std::array 不會自動退化成 T* // int *arr_p = arr;
|
當我們開始用上了 std::array 時,難免會遇到要將其兼容 C 風格的接口,這里有三種做法:
void foo(int *p, int len) { return; }
std::array<int, 4> arr = {1,2,3,4};
// C 風格接口傳參 // foo(arr, arr.size()); // 非法, 無法隱式轉換 foo(&arr[0], arr.size()); foo(arr.data(), arr.size());
// 使用 `std::sort` std::sort(arr.begin(), arr.end());
|
std::forward_list
std::forward_list 是一個列表容器,使用方法和 std::list 基本類似,因此我們就不花費篇幅進行介紹了。
需要知道的是,和 std::list 的雙向鏈表的實現(xiàn)不同,std::forward_list 使用單向鏈表進行實現(xiàn), 提供了 O(1) 復雜度的元素插入,不支持快速隨機訪問(這也是鏈表的特點), 也是標準庫容器中唯一一個不提供 size() 方法的容器。當不需要雙向迭代時,具有比 std::list 更高的空間利用率。
來源:https://changkun.de/modern-cpp/zh-cn/04-containers/
C++ 面試必問:深入理解虛函數(shù)表
很多人搞不清 C++ 中的 delete 和 delete[ ] 的區(qū)別
看懂別人的代碼,總得懂點 C++ lambda 表達式吧
Java、C++ 內存模型都不知道,還敢說自己是高級工程師?
C++ std::thread 必須要熟悉的幾個知識點
現(xiàn)代 C++ 并發(fā)編程基礎
現(xiàn)代 C++ 智能指針使用入門
c++ thread join 和 detach 到底有什么區(qū)別?
C++ 面試八股文:list、vector、deque 比較
C++經典面試題(最全,面中率最高)
C++ STL deque 容器底層實現(xiàn)原理(深度剖析)
STL vector push_back 和 emplace_back 區(qū)別
了解 C++ 多態(tài)與虛函數(shù)表