C++ 知識總結 P04:迭代器與演算法庫
阿新 • • 發佈:2020-08-13
迭代器
迭代器用於遍歷容器。迭代器比較重要的一點是 end() 對應的迭代器並不指向結尾元素,而是結尾元素的後面一個,是無法解引用的。
雖然都是通過相同的介面獲得迭代器,但是不同的容器返回的迭代器是有差別的。
- 前向迭代器:無序容器返回的迭代器型別, 只能使用
++
前進。 - 雙向迭代器:關聯容器返回的迭代器型別,可以使用
++
和--
前進和回退。 - 隨機訪問迭代器:序列容器返回的迭代器型別,不僅有雙向迭代器的能力,還可以使用
+=n
和-=n
的雙向偏移。
迭代器輔助函式
advance(iter, n)
:原地修改,相當於+=n
三種迭代器都支援,但不檢查是否越界。next(iter)
prev(iter)
:非原地修改,相當於+1
與-1
,但不檢查越界。這兩個函式也有移動多個位置的版本。distance(iter1, iter2)
此外還要注意一些容器不支援反向迭代器。
範圍 for
範圍 for 可以方便地迭代容器,只要操作的物件 coll
滿足以下條件之一:
- 有
begin()
,end()
成員函式; - 可以作為全域性性的
begin()
,end()
函式的實參; - 是
initializer_list
,也即使用{}
包圍而資料; - 是一個數組。
就可以使用範圍 for。注意靈活地使用 &
避免不必要的拷貝。
函式作為引數
普通函式、函式物件 和 Lambda 都可以作為函式引數。
Lambda
[<capture>](<parameter>){<statements>} // parameter: 引數傳遞 // statmements: 執行語句 // capture: 指明與外部作用域的關係 // [=] lambda 內部可以讀取所有外部作用域的資料; // [&] lambda 內部可以讀寫所有外部作用域的資料; // [x, &y] lambda 內部可以讀取外部的 x,但不能修改;可以讀寫外部的 y // (x, &y) 此時的 x, y 都是形參,在 lambda 內部修改 x 不會對外部的實參產生影響,但是修改 y 實際是修改外部的實參。 // 一些使用 lambda 的方法 auto cmp = [] (int x, int y) { return x < y; }; bool result = [](int x, int y) { return x < y; } (100, 50); // lambda 直接呼叫 sort(vec.begin(), vec.end(), [](auto& e1, auto& e2){ return e1.size() < e2.size(); });
使用 lambda
auto cmp = [](int a, int b){ return a < b; };
sort(v.begin(), v.end(), cmp);
使用普通函式
bool cmp(int a, int b) { return a < b; }
sort(v.begin(), v.end(), cmp);
使用普通物件
struct cmp {
bool operator()(int a, int b) { return a < b; }
};
sort(v.begin(), v.end(), cmp()); // 注意這裡多加了一個括號
演算法庫
演算法庫中包含許多不同功能的函式,涵蓋比較廣, 可以參考 C++ Reference / Algorithm。僅僅閱讀文件可能無法弄清楚這些成員函式的具體表現,需要在實踐中多累積經驗。