在boost.foreach中操作迭代器

boost.foreach库使用起来非常方便,但实现的技巧可算是精彩绝伦。写基础库就应该如此,困难的永远留给自己,将光鲜的一面奉献出来。
 简单使用示例:    
  std::vector<int> vecs;
  vecs.push_back(1);
  vecs.push_back(2);
  vecs.push_back(3);
  vecs.push_back(4);
  vecs.push_back(5);

  BOOST_FOREACH(int index, vecs) {
    _asm nop;
  }
 顺序遍历十分方便,但有时候想获取更多的信息(如:当前遍历的位置索引等),就不得不需要获取到当前的迭代器位置。
 观察foreach的内部实现,_foreach_cur变量存放当前迭代器的信息,但也仅仅如此,无法直观地获取具体的迭代器类型。
 要使用_foreach_cur变量,必须书写相应的辅助函数.

下面以获取foreach的两个迭代器之间的距离为例: 

namespace boost {
namespace foreach_detail_ {
  
template<typename T, typename C>
inline 
typename boost::iterator_difference<BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type>::type
    distance(auto_any_t first, auto_any_t last, type2type<T, C> *)
{
  typedef BOOST_DEDUCED_TYPENAME foreach_iterator<T, C>::type iter_t;
  return std::distance(auto_any_cast<iter_t, boost::mpl::false_>(first),
    auto_any_cast<iter_t, boost::mpl::false_>(last));
}

// namespace foreach_detail_
// namespace boost

 获取当前的迭代位置到容器开始的距离:

#define BOOST_FOREACH_DISTANCE(COL)   \
  boost::foreach_detail_::distance(BOOST_FOREACH_BEGIN(COL), _foreach_cur, BOOST_FOREACH_TYPEOF(COL))

宏参数COL为容器变量或者返回值为容器的函数,根据foreach的实现技巧,该参数并不会被求值,仅仅用其做模板参数的推导。

使用示例:

  BOOST_FOREACH(int index, vecs) {
    assert(index == BOOST_FOREACH_DEREF(vecs));
    size_t dis = BOOST_FOREACH_DISTANCE(vecs);
    _asm nop;
  }
posted @ 2012-11-27 10:07  孤竹君  阅读(2524)  评论(4编辑  收藏  举报