繁体   English   中英

具有while循环的C ++ 11反向迭代器

[英]C++11 reverse iterator with while loop

我知道代码不是一个好习惯,所以问题不在于此。 我只想了解以下示例的工作方式。 注意,当我调用remove时,我对迭代器不做任何事情,因此当循环进入下一个迭代时,它如何指向下一个元素?

#include <string>
#include <list>
#include <algorithm>
#include <iostream>

class Obj;
std::list<Obj> objs;

class Obj
{
public:
  Obj(const std::string& name, int age)
  : name_(name), age_(age)
  {}

  std::string name()
  {
    return name_;
  }

  int age()
  {
    return age_;
  }
private:
  std::string name_;
  int age_;
};


void remove(const std::string& name)
{
  auto it = find_if(objs.begin(), objs.end(),[name] (Obj& o) { return (o.name() == name); });
  if (it != objs.end())
  {
    std::cout << "removing " << it->name() << std::endl;
    objs.erase(it);
  }
}

int main()
{
  objs.emplace_back("bob", 31);
  objs.emplace_back("alice", 30);
  objs.emplace_back("kevin", 25);
  objs.emplace_back("tom", 45);
  objs.emplace_back("bart", 37);
  objs.emplace_back("koen", 48);
  objs.emplace_back("jef", 23);
  objs.emplace_back("sara", 22);

  auto it = objs.rbegin();
  while (it != objs.rend())
  {

   std::cout << it->name() << std::endl;

   if (it->name() == "tom")
   {
      remove(it->name()); //notice I don't do anything to change the iterator
   }
   else
   {
     ++it;
   }
  }
  return 0;
}

以下是输出:

sara
jef
koen
bart
tom
removing tom
kevin
alice
bob

您可以通过删除迭代器所针对的对象来使其无效 (无论是否为此目的使用了它的值)。 如果你尝试之后访问它的行为是不确定的(阅读:什么都可能发生,就像同it跳跃到下一个元素,或者你的程序崩溃)。 您不能将其依赖于其他任何行为。

我的其他答案不正确。 观察到的行为归因于reverse_iterator的实现。 来自cppreference

std::reverse_iterator是一个迭代器适配器 ,可反转给定迭代器的方向。 换句话说,当提供了双向迭代器时, std::reverse_iterator会生成一个新的迭代器,该迭代器将从底层双向迭代器定义的序列的末尾开始移动。

对于由迭代器i构造的反向迭代器r ,关系&*r == &*(i-1)始终为真(只要r是可取消引用的); 因此,从一端到最后的迭代器构造的反向迭代器将引用序列中的最后一个元素。

(强调我的)。 另请参见[reverse.iterator]

OK,这是什么意思为我们:当一个反向迭代it指向“汤姆”,它实际上环绕一个前向迭代到下一个元素,“捷运”。 当您取消引用它时,它将在包装的迭代器之前使用一个元素,即在“ bart”之前的元素,后者实际上是“ tom”。

当您删除“ tom”时,包装的迭代器不会更改。 (它们都没有失效。)它仍然指向“ bart”。 当您取消引用反向迭代器时,它将查找“ bart”( 现在为“ kevin”)之前的内容。

这意味着您不会真正导致不确定的行为。 如果在第60行调用了remove("bart") ,则可能会。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM