2012-08-13 84 views
8

進一步滿足輸出迭代器要求的迭代器被稱爲可變迭代器。不可變迭代器被稱爲不變迭代器。 [24.2.1:4]增加可變輸入迭代器是否使舊迭代器值失效?

這表明你可以有一個可變的輸入迭代器,它滿足輸入和輸出迭代器的要求。

遞增輸入迭代器後,其舊值的副本不需要可解引用[24.2.3]。但是,標準對輸出迭代器來說並不一樣;實際上,後綴增量的操作語義爲{ X tmp = r; ++r; return tmp; },表明輸出迭代器可能不會使舊迭代器值無效(副本)。

所以,可以增加一個可變的輸入迭代器使舊的迭代器副本失效?

如果是這樣,您將如何支持代碼如X a(r++); *a = tX::reference p(*r++); p = t(例如)代理對象?

如果不是,那麼爲什麼boost::iterator聲稱它需要代理對象? (鏈接是代碼;向下滾動閱讀關於struct的評論writable_postfix_increment_proxypostfix_increment_result)。也就是說,如果您可以返回舊迭代器值的(可解除引用的)副本,那麼爲什麼您需要將此副本包裝在代理中?

+4

@MarkRansom是的,當人們試圖理解他們正在使用的語言時,我確信討厭。他們都是這樣的......我需要在* this *註釋中告訴世界我的仇恨在這裏(對於記錄來說,迭代器類別在C++中是一個大問題,瞭解它們每個都可以做什麼是非常有用的) – jalf 2012-08-13 08:10:21

+0

@MarkRansom:我的問題對我很重要,因爲肯定的答案意味着我必須向我的類中添加另一個代理對象來處理可變輸入迭代器,就像Boost一樣。下面的共識表明,不存在可變輸入迭代器(儘管在24.2.1:4中有評論)。這反過來表明Boost在處理「可變輸入迭代器」時是不正確的---如果即使Boost開發者誤解了這個標準的這個方面,這不是一個應該解決的問題嗎? – nknight 2012-08-13 19:58:14

回答

6

其中指出如何將這些從輸入和輸出迭代不同,如果在接下來的部分中找到的解釋,[24.2.5]轉發迭代器,:

兩個提領迭代a和類型的bX報價所述多遍保證如果:

- a == b++a == ++b意味着
和 - X是指針類型或表達(void)++X(a), *a等於表達式*a。 (注意:a == b意味着++a == ++b(對於輸入和輸出迭代器不是這樣)並且通過可變迭代器(適用於輸出迭代器)去除賦值次數限制的要求)允許使用具有正向迭代器的多通單向算法。 末端注]

不幸的是,這個標準必須被理解爲一個整體,並且說明是不是總是在那裏你希望它是。

+0

我還是很困惑,對不起。你是否說可變輸入迭代器不使舊值失效,它必須滿足多通保證?我感謝你的回答! – nknight 2012-08-13 06:48:54

+2

不,我是說需要一個前向迭代器來做你想做的事情,一個輸入迭代器不是。標準之間沒有任何內容。即使你有一些前向迭代器的屬性,它仍然是一個輸入或輸出迭代器,直到全部*需求被滿足。考慮一個輸入迭代器可以連接到一個密鑰。即使您保存了該文件的副本,也無法備份並讓我重新輸入文本。類似於輸出迭代器,它可以直接到打印機。 – 2012-08-13 06:58:30

+2

哦!我將保存該鍵盤/打印機的比喻以供將來再次使用:D – 2012-08-13 08:49:56

4

輸入和輸出迭代器基本上被設計爲允許單遍遍歷:描述每個元素只能訪問一次的序列。

流是一個很好的例子。如果您從stdin或套接字讀取,或者寫入文件,則只有流的當前位置。指向相同基礎序列的所有其他迭代器在增加迭代器時都會失效。

前向迭代器允許多傳球穿越,你需要額外的保證:他們確保您可以複製你的迭代,遞增原件,副本將仍然指向舊的位置,這樣你就可以從那裏迭代。

+0

「*所有其他指向相同基礎序列的迭代器在增加迭代器時都會失效*」---事實上,這是標準的意圖(對於輸入和輸出迭代器),儘管C++ 11不會不要爲輸出迭代器明確這一點,因爲此修復程序:(http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#2035)未將其納入發佈版本(有關更多詳細信息,請參閱http://stackoverflow.com/a/11938988/985943)。 – nknight 2012-08-13 20:18:51