访问BOOST_FOREACH循环中的迭代器

时间:2009-06-09 11:30:01

标签: c++ boost iterator foreach

我有一个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。有没有办法解决这个问题?

3 个答案:

答案 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)