2010-07-08 90 views
17

boost的文檔specialized iterator adaptors指出boost::reverse_iterator「糾正了C++ 98的std :: reverse_iterator的很多缺點。」std :: reverse_iterator有什麼缺點?

這些缺點是什麼?我似乎無法找到這些缺點的描述。

後續問題:

如何提高:: reverse_iterator的糾正這些缺點?

+1

它往往有點.....早產。 – 2010-07-08 20:27:33

+0

作爲評論發佈,因爲我只是猜測:'std :: reverse_iterator <>'的早期實現有時會有錯誤。 Boost可能只是試圖隔離這種情況。也許這個評論更多的是關於'reverse_iterator'實現中的缺點,而不是標準中的缺點? – 2010-07-08 20:52:41

回答

10

嗯,最大的問題是他們不是轉發迭代器,而且有些東西幾乎期望了前向迭代器。所以,你必須做一些有趣的轉換才能使事情發揮作用。要列舉一些問題

  1. erase()某些版本和insert()需要迭代器,而不是反向迭代器。這意味着如果您使用的是反向迭代器,並且您想要insert()erase(),那麼您將不得不使用反向迭代器的base()函數來實現前向迭代器。沒有自動轉換。

  2. base()根據插入返回等價於反向迭代器的前向迭代器。也就是說,將插入插入到當前元素的前面。因此,如果base()爲您指定了指向相同元素的迭代器,則反向迭代器指向的元素將是指向的錯誤元素。所以,它指向前進一步,你可以使用它來插入。

  3. 因爲base()返回一個指向不同元素的迭代器,所以它是erase()的錯誤元素。如果您在base()的迭代器上調用erase(),則會從容器中刪除反向迭代器指向的元素中的一個元素,因此您必須在調用base()之前遞增反向迭代器,以便獲得正確的前向迭代器用於erase()

  4. 是否可以使用base()erase()正確擦除元素完全取決於您的實現。它適用於gcc,但對於Visual Studio,它們實際上只是包裝一個前向迭代器,以便在處理逆向迭代器和Visual Studio時無法使用erase()。我不記得insert()是否有同樣的問題,但是反向迭代器在C++的不同實現之間工作不一樣(根據Visual Studio人員,標準不夠清楚),所以它可能有點毛將它們用於除了遍歷容器之外的其他任何東西。

可能有其他一些問題,但處理的不是非常量,前向迭代用C++做的比簡單地在一個容器的遍歷其它任何時候能有點毛茸茸的其他任何類型的迭代器 - 如果你甚至可以做到這一切 - 因爲這麼多的函數需要非常量前向迭代器而不是任何其他類型的迭代器。

如果你真的想知道各種迭代類型和與它們相關的問題之間的差異,我推薦閱讀Scott Meyer的Effective STL。它對迭代器有很大的幫助。

編輯:至於如何Boost的逆迭代糾正這些缺點,恐怕我沒有線索。我意識到一些標準的反向迭代器的缺點,並且在過去被它們咬了,但是我從來沒有用過Boost,所以我對它們的反向迭代器根本不熟悉。抱歉。

+1

我不確定我看到你在看什麼。 「預計」前向迭代器的代碼不應該「注意到」任何區別,除非它們執行未定義的行爲...... – Cogwheel 2010-07-08 20:31:39

+1

C++ 03中的std :: reverse_iterator模板公開了與基礎迭代器相同的迭代器類別必須至少是一個雙向迭代器,所以reverse_iterator總是至少是一個雙向迭代器(因此也是一個前向迭代器)。 – 2010-07-08 20:35:30

+1

我不相信你在這裏是正確的。我認爲reverse_iterator實際上是一個前向迭代器。至少我不知道它違反了這個概念。 – 2010-07-08 20:35:49