為什麼STL的很多container的range version insert函式實現都有input iterator和forward iterator兩個過載?

時間 2021-06-02 10:40:15

1樓:QAMichaelPeng

以vector::insert(const_iter where, iter first, iter last)為例,如果引數為forward_iter,則可以多次遍歷訪問。先用一次遍歷訪問求出待插入元素個數,預分配好記憶體,就可以減少記憶體分配的開銷。

而input_iterator只能訪問一次,不能預先計算出待插入的元素個數,只能逐個插入,可能帶來多次記憶體分配,開銷增大。

同理在用distance求元素個數的時候又有針對forward_iter和random_access_iter的不同過載,也是效率考量使然。forward_iter不支援iter2-iter1操作,只能逐個遍歷過去求距離, 時間複雜度O(n),而random_access_iter則支援iter2-iter1,時間複雜度O(1).

2樓:

forward_iterator是要滿足multi-pass guarantee的,說白了是可以重頭來過。而input_iterator語義上只允許順序訪問一次。

這個區別看一下異常處理部分就清楚了,用input_iterator只能提前記住插入了多少個元素,因為它是不可以再次被使用的,而forward_iterator可以先儲存乙個初始值,出現異常時候重新使用。

3樓:dontbeatmycat

《elements of programming》專門講了這些迭代器的區別

Input Iterator 是 single pass 的,也就是說,它的 successor 操作不是 regular 的,

Forward Iterator 則是 Input Iterator + regular 的 successor 操作,也就是說,它可以重複使用。

如果事先計算好實際插入的元素個數,那麼 range insert 時可以更方便地分配空間(對於vector),在計算元素個數時,如果迭代器是 random-access 的,那麼計算元素個數很簡單(求個差就行了),但是,如果迭代器只是 forward 的,就必須反覆 ++ 並計數(參考 distance - C++ Reference 的開頭,以及Iterator validity部分 ),如果迭代器只是個 input 的,那麼甚至無法進行計數(因為 Input Iterator 只能迭代一次,計數完就不能再用了),只能乙個個插入(參考 vector::insert 中的 complexity 部分) ,效率比較低。

對於 list 而言,事先計算插入元素個數沒有必要,因為 list 本身就不是連續儲存的,所以兩種迭代器的實現是差不多的。

個人理解,不一定對 = =

4樓:鄒曉航0號

這個是stl迭代器的分類圖

在《STL原始碼剖析》裡面有一段話是這麼說的:在設計演算法時,如果可能,我們盡量針對上圖中的某種迭代器提供乙個明確定義,並針對更強化的某種迭代器提供另一種定義,這樣才能在不同的情況下提供最大的效率。

由於input iterator和forward iterator是不同種類的迭代器,且前者唯讀後者可寫可讀,因此會提供不同版本的實現來在某種情況下達到最優的效率吧

stl裡為什麼要用size type,而不直接用unsigned int 他們兩者其實是一回事吧

因為兩者不是一回事。拿 memcpy void dst,void const src,size t n 舉例,在乙個 I16P32 的機器上,處理器明明理論上最多可以複製 位元組,但如果引數 n 用 unsigned int 的話最大就只能複製 個位元組了。各個平台資料表示方式的記法 其中 I 指 ...

為什麼STL沒有提供通用的小物件優化(SSO SBO SOO Arena等)的實現?

Dot Blue 綜合來說,一部分是歷史原因,一部分是通用實現難以達到內部實現的效果。SSO Small Size Optimization 出現的目的無非是讓小物件的記憶體往棧上而不是堆上放。如果有SSO和無SSO的差別僅僅是是否根據分配大小決定存放的地方不同,那通用的SSO就應該通過分配器all...

STL原始碼剖析中,為什麼空間配置器的union obj最後要跟乙個char陣列?

指北 這個union殺了我很多時間,在這留個記錄說不定以後能幫到別人結合 stl原始碼剖析 p65 p67來看 這東西沒有實際用處,或者說它不必要 要達到用16個鍊錶串起記憶體的效果,用struct node 就夠了因為一旦記憶體塊返回給客戶端,next就沒用了。直接對這塊記憶體覆寫使用即可 猜測寫...