vector vec = {0,1,1,2,3,5,8,13,21,55,89};
auto it = vec.begin();
while (it != vec.end()) {
if (*it % 2)
vec.erase(it); // 錯誤:erase 使 it 失效
else
++it;
}
`vector::erase` 會將後續元素前移,**導致原迭代器 `it` 失效**(指向已被移動/銷毀的記憶體)。後續 `++it` 或比較 `it != vec.end()` 即為未定義行為,MSVC Debug 模式下拋出 `vector iterator incompatible`。
`erase` 返回**指向被刪除元素下一個位置的有效迭代器**。
while (it != vec.end()) {
if (*it % 2)
it = vec.erase(it); // 關鍵:接收返回值更新 it
else
++it;
}
| 操作 | vector | deque | list/forward_list | map/set |
|---|---|---|---|---|
| `erase` | **失效**(被刪除及之後) | **失效**(被刪除及之後) | **僅被刪除者失效** | **僅被刪除者失效** |
| `insert`/`push_back` | **可能失效**(重新配置時) | **失效** | **不失效** | **不失效** |
| 返回值可用 | `erase`、`insert` | `erase`、`insert` | `erase`、`insert`、`splice` | `insert`、`erase` |
#include
std::erase_if(vec, [](int x){ return x % 2 != 0; }); // 直接移除所有奇數
// remove-erase 慣用語
vec.erase(std::remove_if(vec.begin(), vec.end(), [](int x){ return x % 2 != 0; }), vec.end());
凡操作 `vector`/`deque`/`string` 等連續容器涉及插入刪除,**必須**使用返回值更新迭代器,或改用演算法 (`remove_if` + `erase` / `erase_if`)。養成查閱容器迭代器失效規則的習慣。