簡體   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