2

我在 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;

我该怎么做这样的事情?

4

2 回答 2

2

已经有关于分段迭代器的提议和讨论,但没有一个真正将其纳入 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";
于 2012-11-20T21:55:57.750 回答
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 (函数输入迭代器也可以很好地工作)。

你在范围内工作。迭代器的内部状态是内部迭代器、外部迭代器和一个标志的元组,表示您是否在最后。Increment 推进内部迭代器,检查它是否等于内部范围的 end,如果是,则推进外部迭代器,直到它到达外部范围的末尾或非空的内部范围(然后将内部迭代器设置为外部迭代器,如果外部迭代器没有结束!)

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

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

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

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

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

于 2012-11-20T21:50:42.930 回答