Boost C++ Libraries: Ticket #11287: adaptors: strided does not support input iterators https://svn.boost.org/trac10/ticket/11287 <p> Hi, </p> <p> Despite what the documentation says, the stride adaptor does not support input iterators. This is a pity, since for instance its applicability to iterators to coroutines: see <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/11274" title="#11274: Bugs: coroutine's iterators don't fully comply (closed: invalid)">#11274</a>. </p> <p> Oliver Kowalke tracked down the issue, and built a small scale example that shows the problem: see <a class="ext-link" href="http://lists.boost.org/boost-users/2015/05/84277.php"><span class="icon">​</span>http://lists.boost.org/boost-users/2015/05/84277.php</a>. The example is repeated below: </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;iterator&gt; #include &lt;vector&gt; #include &lt;boost/range.hpp&gt; #include &lt;boost/range/adaptor/strided.hpp&gt; namespace foo { template&lt; typename T &gt; class X { private: typedef std::vector&lt; T &gt; vec_t; vec_t vec_; public: X( vec_t const&amp; vec) : vec_( vec) { } class iterator : public std::iterator&lt; std::input_iterator_tag, T &gt; { private: X * x_; typename vec_t::iterator i_; public: typedef typename iterator::pointer pointer_t; typedef typename iterator::reference reference_t; iterator() : x_( 0), i_() {} explicit iterator( X * x) : x_( x), i_( x_-&gt;vec_.begin() ) {} iterator( iterator const&amp; other) : x_( other.x_), i_( other.i_) {} iterator &amp; operator=( iterator const&amp; other) { if ( this == &amp; other) return * this; x_ = other.x_; i_ = other.i_; return * this; } bool operator==( iterator const&amp; other) const { return other.x_ == x_ &amp;&amp; other.i_ == i_; } bool operator!=( iterator const&amp; other) const { return other.x_ != x_ || other.i_ != i_; } iterator &amp; operator++() { ++i_; return * this; } iterator operator++( int) { i_++; return * this; } reference_t operator*() const { return * i_; } pointer_t operator-&gt;() const { return &amp; ( * i_); } }; class const_iterator : public std::iterator&lt; std::input_iterator_tag, const T &gt; { private: X * x_; typename vec_t::const_iterator i_; public: typedef typename iterator::pointer pointer_t; typedef typename iterator::reference reference_t; const_iterator() : x_( 0), i_() {} explicit const_iterator( X * x) : x_( x), i_( x_-&gt;vec_.begin() ) {} const_iterator( const_iterator const&amp; other) : x_( other.x_), i_( other.i_) {} const_iterator &amp; operator=( const_iterator const&amp; other) { if ( this == &amp; other) return * this; x_ = other.x_; i_ = other.i_; return * this; } bool operator==( const_iterator const&amp; other) const { return other.x_ == x_ &amp;&amp; other.i_ == i_; } bool operator!=( const_iterator const&amp; other) const { return other.x_ != x_ || other.i_ != i_; } const_iterator &amp; operator++() { ++i_; return * this; } const_iterator operator++( int) { i_++; return * this; } reference_t operator*() const { return * i_; } pointer_t operator-&gt;() const { return &amp; ( * i_); } }; friend class iterator; friend class const_iterator; }; template&lt; typename T &gt; typename X&lt; T &gt;::iterator range_begin( X&lt; T &gt; &amp; c) { return typename X&lt; T &gt;::iterator( &amp; c); } template&lt; typename T &gt; typename X&lt; T &gt;::const_iterator range_begin( X&lt; T &gt; const&amp; c) { return typename X&lt; T &gt;::const_iterator( &amp; c); } template&lt; typename T &gt; typename X&lt; T &gt;::iterator range_end( X&lt; T &gt; &amp;) { return typename X&lt; T &gt;::iterator(); } template&lt; typename T &gt; typename X&lt; T &gt;::const_iterator range_end( X&lt; T &gt; const&amp;) { return typename X&lt; T &gt;::const_iterator(); } template&lt; typename T &gt; typename X&lt; T &gt;::iterator begin( X&lt; T &gt; &amp; c) { return boost::begin( c); } template&lt; typename T &gt; typename X&lt; T &gt;::const_iterator begin( X&lt; T &gt; const&amp; c) { return boost::begin( c); } template&lt; typename T &gt; typename X&lt; T &gt;::iterator end( X&lt; T &gt; &amp; c) { return boost::end( c); } template&lt; typename T &gt; typename X&lt; T &gt;::const_iterator end( X&lt; T &gt; const&amp; c) { return boost::end( c); } } namespace boost { template&lt; typename T &gt; struct range_mutable_iterator&lt; foo::X&lt; T &gt; &gt; { typedef typename foo::X&lt; T &gt;::iterator type; }; template&lt; typename T &gt; struct range_const_iterator&lt; foo::X&lt; T &gt; &gt; { typedef typename foo::X&lt; T &gt;::const_iterator type; }; } int main() { std::vector&lt; int &gt; vec = { 1,2,3,4,5,6,7,8,9,10 }; auto x = foo::X&lt; int &gt;( vec); for (auto i : x | boost::adaptors::strided( 2) ) std::cout &lt;&lt; i &lt;&lt; " "; std::cout &lt;&lt; '\n'; } </pre> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11287 Trac 1.4.3