使用常规迭代器向后迭代,还是使用reverse_iterator?

Dan*_*Dan 9 c++ iterator stl

我最近了解了在C++中使用反向迭代器的正确方法(特别是当你需要擦除它时).(见这个问题,并且这一个.)

这就是你应该这样做的方式:

typedef std::vector<int> IV;
for (IV::reverse_iterator rit = iv.rbegin(), rend = iv.rend();
     rit != rend; ++rit)
{
  // Use 'rit' if a reverse_iterator is good enough, e.g.,
  *rit += 10;
  // Use (rit + 1).base() if you need a regular iterator e.g.,
  iv.erase((rit + 1).base());
}
Run Code Online (Sandbox Code Playgroud)

但我认为这样做要好得多(不要这样做,不符合标准,正如MooingDuck指出的那样):

for (IV::iterator it = iv.end(), begin = iv.begin();
     it-- != begin; )
{
  // Use 'it' for anything you want
  *it += 10;
  iv.erase(it);
}
Run Code Online (Sandbox Code Playgroud)

缺点:

  • 你告诉我. 它出什么问题了?
  • 正如MooingDuck指出的那样,它不符合标准.这几乎取代了以下任何可能的优势.

优点:

  • 使用熟悉的习惯用于反向for循环
  • 不必记住(或解释) +1
  • 减少打字
  • 也适用于std :: list: it = il.erase(it);
  • 如果擦除元素,则不必调整迭代器
  • 如果擦除,则不必重新计算begin迭代器

Bil*_*eal 7

反向迭代器的原因是标准算法不知道如何向后迭代集合.例如:

#include <string>
#include <algorithm>
std::wstring foo(L"This is a test, with two letter a's involved.");
std::find(foo.begin(), foo.end(), L'a'); // Returns an iterator pointing
                                        // to the first a character.
std::find(foo.rbegin(), foo.rend(), L'a').base()-1; //Returns an iterator
                                                 // pointing to the last A.
std::find(foo.end(), foo.begin(), L'a'); //WRONG!! (Buffer overrun)
Run Code Online (Sandbox Code Playgroud)

使用任何迭代器都可以获得更清晰的代码.