如何在C ++中定义自定义迭代器

时间:2012-11-20 21:28:20

标签: c++ iterator

我在SO上看过很多关于如何定义自定义迭代器的帖子,但似乎没有什么能够完全回答我的问题,那就是......

如何创建隐藏嵌套for循环的迭代器?

例如,我有一个类Foo,Foo内部是一个Bar,而Bar内部是一个字符串。我可以写

for (const Foo& foo : foo_set)
  for (const Bar& bar : foo.bar_set)
    if (bar.my_string != "baz")
      cout << bar.my_string << endl;

但我希望能够做到这样的事情:

for (const string& good : foo_set)
  cout << good << endl;

我该怎么办?

2 个答案:

答案 0 :(得分:2)

proposalssegmented iterators的讨论,但实际上没有一个进入C ++标准(无论如何)。

现在看来,关于处理它的最干净的方法(IMO,无论如何)是作为一个项目的集合,每个项目本身就是一个集合:

std::ostream &operator<<(std::ostream &os, bar const &b) { 
     return os << b.my_string;
}

std::ostream &operator<<(std::ostream &os, foo const &f) { 
     std::remove_copy_if(f.begin(), f.end(), 
                         std::ostream_iterator<bar>(os, "\n"),
                         [](bar const &b) { return b.my_string != "baz"; });

     return os;
}

std::copy(foo_set.begin(), foo_set.end(), 
          std::ostream_iterator<foo>(std::cout, "\n"));

或者,如果你坚持:

for (auto s : foo_set)
    std::cout << s << "\n";

答案 1 :(得分:1)

什么,你想要更多细节?

这可以帮助很多: http://www.boost.org/doc/libs/1_52_0/libs/iterator/doc/index.html#iterator-facade-and-adaptor

或者: http://www.boost.org/doc/libs/1_52_0/libs/iterator/doc/iterator_facade.html#usage (函数输入迭代器也可以正常工作)。

你在范围上工作。迭代器的内部状态是内部迭代器,外部迭代器的元组,以及一个标记,如果你在最后。递增推进内部迭代器,检查它是否等于内部范围的结束,如果是,则推进外部迭代器直到它到达外部范围的末尾或非空的内部范围(然后将内部迭代器设置为内部迭代器的开头)外迭代器,如果外迭代器没有结束!)

取消引用只是取消引用内部迭代器。盲目! (好吧,抛出一些断言)

等于检查外部迭代器是否相等,如果是,则检查是否设置了“结束标志”。如果不是,它将内部迭代器相等。 (有没有一种优雅的方法来避免那个结束标志?)

获取第一个元素包括找到第一个非空内部范围的迭代器。

减量有点棘手,但不是你的任务所必需的。

在外迭代器有效时,必须注意避免使用无效的内迭代器。我想我列出了上面的大部分问题。