在 C/C++ 中,裸指針雖強大但極易導致記憶體洩漏(如 new 後未 delete、異常拋出導致釋放邏輯跳過)。C++ 引入**智能指針**(如已棄用的 auto_ptr、現代的 unique_ptr/shared_ptr)透過 RAII 機制自動管理生命週期。**迭代器**正是 STL 對「智能指針」思想的另一種應用:封裝原始指針操作,提供統一、安全、泛型的容器遍歷介面。
STL 六大組件中,迭代器扮演「中介者」角色。以 find 為例:
vector<int> vec = {0,1,2,3,4,5,6,7,8,9};
auto it = find(vec.begin(), vec.end(), 7);
find 原型為 template<class InputIt, class T> InputIt find(InputIt first, InputIt last, const T& val)。它完全不關心底層容器是 vector、list 還是 deque,只需輸入迭代器支援 ++、==、!=、解引用即可。這正是**泛型程式設計**的精髓:算法與容器解耦,迭代器提供統一協定。
| 類別 | 可讀/寫 | 支援操作 | 典型容器 |
|---|---|---|---|
| Input Iterator | 唯讀 | ++, ==, != | istream_iterator |
| Output Iterator | 唯寫 | ++ | ostream_iterator |
| Forward Iterator | 讀寫 | ++, ==, != | forward_list |
| Bidirectional Iterator | 讀寫 | ++, --, ==, != | list, set, map |
| Random Access Iterator | 讀寫 | ++, --, [], +n, -n, 比較運算 | vector, deque, string |
**關鍵繼承關係**:RandomAccess → Bidirectional → Forward → Input。派生類物件可隱式轉型為基類參數,故 vector::iterator(Random Access)可直接傳給要求 InputIterator 的 find。
每個容器內部實現不同,其迭代器行為亦異。**迭代器失效**指原指向元素被移動或銷毀,繼續使用會導致未定義行為。
push_back, insert):
capacity 變化)→ 所有迭代器失效erase, pop_back, clear):被刪除元素及其**之後**的迭代器失效size > capacity → 全部失效size < capacity 且縮小 → 被切除元素的迭代器失效push_front/back:**不失效**標準庫通過以下機制實現泛型操作:
input_iterator_tag 等空結構體,用於函式重載分派(如 distance, advance)。iterator_category, value_type, difference_type, pointer, reference)。distance(輸入迭代器 O(n)、隨機存取 O(1))、advance(根據類別選擇 ++ 迴圈或 +=n)。auto + begin()/end(),避免手寫冗長型別。it = vec.erase(it);(回傳下一個有效迭代器)。vec.reserve(N) 減少擴容導致的迭代器失效。list;需隨機存取用 vector;鍵值查找用 unordered_map。迭代器是 STL 泛型架構的基石,理解其分類、失效規則與實現原理,能讓你寫出更健壯、高效的 C++ 代碼。下次當你看到 for (auto& x : container) 時,腦海中應浮現的是「這是一個安全、統一、零成本的抽象」,而非單純的語法糖。