使用 forward_list 是因為它內存占用更小且在特定場景下操作更高效。forward_list 是單鏈表,每個節點僅保存下一個節點指針,相比 list 節省內存;不支持隨機訪問和反向遍歷,但中間插入刪除效率高;沒有 size() 函數,需手動計算元素數量;提供 insert_after 和 erase_after 等接口,適合頭部或中間頻繁操作的場景;支持合并鏈表、實現 lru 緩存邏輯、配合 emplace_after 使用以及利用 before_begin() 迭代器等技巧,在性能敏感或內存受限環境下具有優勢。
c++ STL 中的 forward_list 是一個單鏈表容器,和 list 這種雙鏈表不同,它只支持單向遍歷。它的設計目標是輕量、高效,在某些特定場景下比其他序列容器更有優勢。
為什么用 forward_list 而不是 list?
最大的區別在于內存占用和操作效率。forward_list 只保存下一個節點的指針,而 list 每個節點都要保存前后兩個指針。如果你不需要反向遍歷,并且在意內存開銷,forward_list 是更合適的選擇。
另一個特點是,forward_list 沒有 size() 成員函數(至少在 C++11 到 C++17 中),只有 empty()。這意味著獲取元素數量需要手動調用 distance,但換來的是更小的內存 footprint。
立即學習“C++免費學習筆記(深入)”;
常見操作需要注意的地方
- 插入和刪除操作通常比 vector 更快,特別是中間插入時不會導致大量元素移動。
- 不支持隨機訪問,只能從頭開始逐個遍歷。
- 提供了 insert_after 和 erase_after 等接口,操作邏輯上與雙鏈表略有不同。
- 因為沒有尾指針,所以在尾部插入(push_front)效率高,但尾部操作不直接支持。
舉個例子:
你想在一個很長的鏈表中間插入一個新元素,這時候用 forward_list 的 insert_after 會比 vector 的 insert 快很多,因為后者可能需要復制大量數據。
特殊用法和技巧
有些時候你可能不太注意 forward_list 的一些隱藏能力:
- 合并多個鏈表:雖然不像 list::splice 那樣方便,但你可以通過迭代器手動拼接多個 forward_list。
- 實現 LRU 緩存的部分邏輯:如果你只需要前向查找,并且頻繁進行頭部或中間插入刪除操作,forward_list 可以作為候選結構。
- 配合 emplace_after 使用:可以避免構造臨時對象,提高性能,尤其適合復雜類型。
- 使用 before_begin() 迭代器:這是 forward_list 獨有的特性,用來輔助插入第一個元素或者統一處理插入邏輯。
這些技巧在實際開發中不一定天天用,但在性能敏感或內存受限的場景下,能帶來明顯優勢。
基本上就這些。