我在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;
我该怎么办?
答案 0 :(得分:2)
有proposals和segmented 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 (函数输入迭代器也可以正常工作)。
你在范围上工作。迭代器的内部状态是内部迭代器,外部迭代器的元组,以及一个标记,如果你在最后。递增推进内部迭代器,检查它是否等于内部范围的结束,如果是,则推进外部迭代器直到它到达外部范围的末尾或非空的内部范围(然后将内部迭代器设置为内部迭代器的开头)外迭代器,如果外迭代器没有结束!)
取消引用只是取消引用内部迭代器。盲目! (好吧,抛出一些断言)
等于检查外部迭代器是否相等,如果是,则检查是否设置了“结束标志”。如果不是,它将内部迭代器相等。 (有没有一种优雅的方法来避免那个结束标志?)
获取第一个元素包括找到第一个非空内部范围的迭代器。
减量有点棘手,但不是你的任务所必需的。
在外迭代器有效时,必须注意避免使用无效的内迭代器。我想我列出了上面的大部分问题。