ใน C++ มี container หลายอย่าง vector, list, set, map ใช้ iterator วนลูป ต้องระวังเพราะ iterator อาจ invalidated ได้ หากรูปทรงหรือขนาดเปลี่ยนแปลง ตัวอย่างต่อไปแสดงปัญหา invalidation
ตัวอย่างปัญหา
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> vec{11, 55, 110, 155, 220};
for (auto it = vec.begin(); it != vec.end(); it++)
if ((*it) == 110)
vec.push_back(89); // แทรกค่าใหม่ขณะวนลูป
for (auto it = vec.begin(); it != vec.end(); it++)
cout << (*it) << " ";
}
ผลลัพธ์
11 55 110 155 220 89 89
ในโปรแกรมนี้ขนาด vector ไม่ได้กำหนดไว้ล่วงหน้า ขณะวนลูปเพิ่มค่า ถ้า vector ไม่มีพื้นที่ จะจองบล็อกหน่วยความจำใหม่และคัดลอกทุกสมาชิก แต่ iterator ยังชี้ที่เก่า อาจเกิด invalidation
กฎสำหรับ iterator invalidation:
| Insertion | Erasure | Resizing | |
|---|---|---|---|
| Vector | Iterator ชี้ก่อนจุดแทรกไม่ได้รับผลกระทบ แต่ตัวอื่น invalid ถ้าขนาดเพิ่ม ทุก iterator invalid | Iterator และ reference หลังจุดลบ invalid ทั้งหมด | เหมือน insert/erase |
| Deque | ทุก iterator และ reference invalid ถ้าแทรกไม่ใช่ท้าย | ลบจากตำแหน่งไหนก็ตามนอกจากท้าย ทุก iterator invalid | เหมือน insert/erase |
| List | ทุก iterator และ reference ไม่ได้รับผล | เฉพาะ iterator/reference ที่ชี้โหนดที่จะลบ ถูกกระทบ | เหมือน insert/erase |
| Set, map, multiset, multimap | ทุก iterator และ reference ไม่ได้รับผล | เฉพาะ iterator/reference ที่ชี้โหนดที่จะลบ ถูกกระทบ | --- |