【问题标题】:boost::iterator_adapter not working with STL algorithmsboost::iterator_adapter 不适用于 STL 算法
【发布时间】:2012-08-18 10:42:28
【问题描述】:

考虑以下“往返”迭代器,它尝试迭代集合中的所有元素,最终再次迭代第一个元素作为其最后一步:

#include <boost/iterator/iterator_adaptor.hpp>

template<typename IteratorBase>
class roundtrip_iterator 
     : public boost::iterator_adaptor< 
          roundtrip_iterator<IteratorBase>, // the derived class overriding iterator behavior
          IteratorBase,                     // the base class providing default behavior
          boost::use_default,               // iterator value type, will be IteratorBase::value_type
          std::forward_iterator_tag,        // iterator category
          boost::use_default                // iterator reference type
       > 
{
private:
  IteratorBase m_itBegin;
  IteratorBase m_itEnd;
  bool m_complete;

public:
  roundtrip_iterator( IteratorBase itBegin, IteratorBase itEnd ) 
    : iterator_adaptor_(itBegin), m_itBegin(itBegin), m_itEnd(itEnd), m_complete(false)
  {}

  void increment()
  { 
    if( m_complete )
    {
      base_reference() = m_itEnd;
      return;
    }

    ++base_reference();

    if(base_reference() == m_itEnd)
    {
      base_reference() = m_itBegin;
      m_complete = true;
    }
  }
};

我现在只实现了增量。

就目前而言,迭代器似乎在标准的“for”循环中运行良好,但我无法让它与 STL 算法一起使用。例如:

int main(int argc, char *argv[])
{
  std::vector<int> v;

  v.push_back(1);
  v.push_back(2);
  v.push_back(3);

  roundtrip_iterator<std::vector<int>::iterator> roundtrip(v.begin(), v.end());

  for( ; roundtrip.base() != v.end(); ++roundtrip)
    std::cout << *roundtrip << std::endl;

  std::cout << std::endl;

  roundtrip_iterator<std::vector<int>::iterator> roundtrip2(v.begin(), v.end());

  std::for_each(
    roundtrip2.base(), v.end(),
    print);

}

打印:

1
2    
3
1 // First element printed out using standard for loop.

1
2
3 // The for_each algo stops here for some reason.

有人知道这两者的区别吗?

【问题讨论】:

    标签: c++ boost stl iterator adaptor


    【解决方案1】:

    通过调用roundtrip2.base(),您实际上将[v.begin(), v.end) 范围传递给std::for_each。你需要能够构造一个过去的值e,这样你就可以传递[roundtrip2, e)

    【讨论】:

    • 所以我调用了 std::for_each(roundtrip2, roundtrip2.end())。这显然涉及在适配器本身上创建一个 end 方法,该方法将一个 const ref 返回到一个虚拟的“one-past-the-end”适配器。不确定这是否是标准习语,还是正确的做法,但它确实有效。我还必须定义自定义 == 和 != 运算符。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    • 2013-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多