1. 程式人生 > 實用技巧 >C++ 知識總結 P04:迭代器與演算法庫

C++ 知識總結 P04:迭代器與演算法庫

迭代器

迭代器用於遍歷容器。迭代器比較重要的一點是 end() 對應的迭代器並不指向結尾元素,而是結尾元素的後面一個,是無法解引用的。
雖然都是通過相同的介面獲得迭代器,但是不同的容器返回的迭代器是有差別的。

  • 前向迭代器:無序容器返回的迭代器型別, 只能使用 ++ 前進。
  • 雙向迭代器:關聯容器返回的迭代器型別,可以使用 ++-- 前進和回退。
  • 隨機訪問迭代器:序列容器返回的迭代器型別,不僅有雙向迭代器的能力,還可以使用 +=n-=n 的雙向偏移。

迭代器輔助函式

  • advance(iter, n) :原地修改,相當於 +=n 三種迭代器都支援,但不檢查是否越界。
  • next(iter)
    , prev(iter) :非原地修改,相當於 +1-1,但不檢查越界。這兩個函式也有移動多個位置的版本。
  • distance(iter1, iter2)

此外還要注意一些容器不支援反向迭代器。

範圍 for

範圍 for 可以方便地迭代容器,只要操作的物件 coll 滿足以下條件之一:

  1. begin(), end() 成員函式;
  2. 可以作為全域性性的 begin(), end() 函式的實參;
  3. initializer_list,也即使用 {} 包圍而資料;
  4. 是一個數組。

就可以使用範圍 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。僅僅閱讀文件可能無法弄清楚這些成員函式的具體表現,需要在實踐中多累積經驗。