2016-01-25 75 views
7

我剛剛寫了下面的代碼,並且非常驚訝它不會編譯:爲什麼不擦除支持反向迭代器?

std::deque<int> container; 
// filling the container... 
for (auto it = container.rbegin(); it != container.rend(); ++it) 
    if (*it == 5) 
    { 
     container.erase(it); 
     break; 
    } 

正如你所看到的,我想刪除符合某種標準的最後一個元素,如果有的話。

的錯誤是

沒有匹配函數調用 的std :: deque的::擦除(的std :: reverse_iterator的...

起初我不相信這是通過反向迭代器造成的,但確實是因爲與begin/end解決它取代rbegin/rend的情況下

所以,2個問題:

  1. 爲什麼不支持?它僅僅是C++委員會忘記包含在標準中的那些小事情之一,還是缺少這種超載的理由?
  2. 什麼是最優雅的方式來做我想要的?我堅持迭代索引?
+4

我想你的答案在這裏:http://stackoverflow.com/questions/1830158/how-to-call-erase-with-a-reverse-迭代器 –

+0

'm_container'和'container',是否一樣? – ZDF

+0

@ZDF:是的,當然。固定。 –

回答

1

我無法回答'爲什麼'的問題,但回答'如何' - 你應該在你的迭代器上調用base()。它將返回一個正確的前向迭代器。

雖然這樣做,請記住反向和前向迭代器之間的關係。一開始可能會讓人困惑,但實際上很簡單。如果你有一個std::vector包含以下項目:

1, 2, 3, 4, 5 

而且你有一個reverse_iterator RIT,其在非關聯給你3,然後*(rit.base)將等於4。要知道爲什麼,只記得在正常的迭代器begin()是可以忽略的,但是end()不是。在反向迭代器中,屬性必須相同 - rbegin()必須是可忽略的,但rend()不應該 - 即應該指向容器的開始之外。

自定義,rend.base()相同begin()(因爲雷德可以構造爲reverse_iterator(begin()),所有上述可容納的唯一途徑,就是如果rend.base()將下一個正確的元素返回到一個超越的開始 - begin() 。很容易看出相同的對稱性適用於rend()

+0

Downvoted的答案,因爲你不能簡單地傳遞'reverse_iterator :: base()'到呃ase'方法。 –

+0

@VioletGiraffe,爲什麼? – SergeyA

+0

因爲它會擦除錯誤的元素!迭代器必須先調整1。 –