سؤال

Consider the following "round trip" iterator, which tries to iterate over all the elements in a collection, eventually iterating over the first element again as its final step:

#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;
    }
  }
};

I have only implemented increment for now.

As it stands, the iterator seems to work well in standard "for" loops, but I can't get it to work with STL algorithms. For example:

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);

}

Prints:

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

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

Does anybody have any ideas as to the difference between the two?

هل كانت مفيدة؟

المحلول

By calling roundtrip2.base(), you're effectively passing the range [v.begin(), v.end) to std::for_each. You need to be able to construct a one-past-the-end value e such that you can pass [roundtrip2, e) instead.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top