首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

std::vector erase 迭代器失效陷阱:erase(it++) vs it=erase(it) 實測差異

     編輯:關於C語言

現象複現

std::vector test = {"a","b","c"};
for (auto it = test.begin(); it != test.end(); ) {
    // 刪除當前元素
    test.erase(it++);  // 寫法 A
    // test.erase(it); it = test.erase(it); // 寫法 B
}

實測差異

寫法刪除最後元素後 it 狀態循環是否正常結束
test.erase(it++)it != test.end() 為 false(表面正常)✅ 正常
it = test.erase(it)it == test.end() 為 true✅ 正常

深度解析

  • erase(it++):後置遞增先取舊值傳給 erase,再遞增 it。erase 內部已使舊迭代器失效,但 it 已遞增指向下一個有效位置(或 end)。行為正確但依賴未規定求值順序,C++17 明確規定參數求值無序,不推薦。
  • it = test.erase(it):標準模式。erase 返回指向被刪除元素下一位置的有效迭代器(或 end),賦值給 it,語義清晰、標準保證。

標準規定

C++11 起 vector::erase 返回 iterator 指向緊隨被刪元素之後的位置。
最佳實踐:it = vec.erase(it); 或範圍刪除 vec.erase(begin, end);

擴展:關聯容器

map/set/unordered_map 的 erase 同樣返回下一迭代器(C++11),同樣適用 it = c.erase(it); 模式。

避坑清單

  1. ❌ vec.erase(it++) —— 依賴求值順序,不可移植
  2. ❌ vec.erase(it); it++; —— erase 後 it 已失效,++ 未定義行為
  3. ✅ it = vec.erase(it); —— 標準、安全、可讀
  4. ✅ 範圍刪除 vec.erase(remove_if(...), vec.end()); —— erase-remove 慣用語

記住 it = erase(it),拒絕迭代器失效陷阱。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved