我有一个BOOST_FOREACH循环来遍历列表。不幸的是,我还需要将迭代器缓存到特定项目。
typedef List::iterator savedIterator;
BOOST_FOREACH(Item &item, list)
{
// stuff...
if (condition)
savedIterator = &item; // this won't work
// do more stuff...
}
显然我可以使用list.begin().. list.end()for循环,但我已经成长为喜欢BOOST_FOREACH。有没有办法解决这个问题?
答案 0 :(得分:7)
这是不可能的,因为您无权访问指向循环内当前项的迭代器。
您可以使用当前项目数据以某种方式从列表中获取迭代器,但我不知道这是否是一个好主意,也是性能方面。
我建议你使用list.begin().. list.end()自己提出的解决方案,这在我看来最容易实现和识别。
答案 1 :(得分:4)
使用Boost.Foreach,你几乎坚持使用对dereferenced迭代器的引用,因为这是Boost.Foreach的设计目的:简化对范围内元素的访问。但是,如果您只是在寻找符合条件的单个元素,那么您可能需要尝试std::find_if()
:
struct criteria {
template <class T>
bool operator()(T const & element) const {
return (element /* apply criteria... */)? true : false;
}
};
// somewhere else
List::iterator savedIterator =
std::find_if(list.begin(), list.end(), criteria());
您还希望在整个列表中应用操作 - 在这种情况下,我建议使用像std::min_element()
或std::max_element()
这样的内容以及像boost::transform_iterator
这样的Boost.Iterators
struct transformation {
typedef int result_type;
template <class T>
int operator()(T const & element) const {
// stuff
int result = 1;
if (condition) result = 0;
// more stuff
return result;
}
};
// somewhere else
List::iterator savedIterator =
std::min_element(
boost::make_transform_iterator(list.begin(), transformation()),
boost::make_transform_iterator(list.end(), transformation()),
).base();
答案 2 :(得分:1)
我有点想知道为什么人们不这样做:
#define foreach(iter_type, iter, collection) \
for (iter_type iter = collection.begin(); iter != collection.end(); ++iter)