Boost C++ Libraries: Ticket #11274: coroutine's iterators don't fully comply https://svn.boost.org/trac10/ticket/11274 <p> Hi! </p> <p> The following example fails to compile cleanly. I use a boost range adaptor to slice an "endless" coroutine, used as a generator: source | strided(10). </p> <pre class="wiki">// begin:header #include &lt;iostream&gt; #include &lt;boost/coroutine/coroutine.hpp&gt; #include &lt;boost/range/adaptor/strided.hpp&gt; using namespace boost::adaptors; using coro_t = boost::coroutines::asymmetric_coroutine&lt;int&gt;; // end:header // begin:func void fibo(coro_t::push_type&amp; sink) { int first = 1, second = 1; sink(first); sink(second); for (;;) { int third = first + second; first = second; second = third; sink(third); } }; // end:func // begin:main int main() { auto source = coro_t::pull_type{fibo}; for (auto i : source | strided(10)) std::cout &lt;&lt; i &lt;&lt; " "; std::cout &lt;&lt; '\n'; } // end:main // CXXFLAGS: -lboost_coroutine-mt -lboost_system-mt </pre><p> It results in: </p> <pre class="wiki">clang++ -stdlib=libc++ -isystem/opt/local/include -std=c++11 -Wall -Wextra -ggdb -L/opt/local/lib -lboost_coroutine-mt -lboost_system-mt -o 6-concurrency/coroutine.exe 6-concurrency/coroutine.cc &amp;&amp; 6-concurrency/coroutine.exe &lt;/dev/null &gt;6-concurrency/coroutine.log.tmp 2&gt;&amp;1 &amp;&amp; mv 6-concurrency/coroutine.log.tmp 6-concurrency/coroutine.log &amp;&amp; { test "1" != 1 || cat 6-concurrency/coroutine.log; } In file included from 6-concurrency/coroutine.cc:3: In file included from /opt/local/include/boost/coroutine/coroutine.hpp:10: In file included from /opt/local/include/boost/coroutine/asymmetric_coroutine.hpp:17: In file included from /opt/local/include/boost/range.hpp:18: In file included from /opt/local/include/boost/range/functions.hpp:20: In file included from /opt/local/include/boost/range/size.hpp:21: In file included from /opt/local/include/boost/range/size_type.hpp:20: In file included from /opt/local/include/boost/range/concepts.hpp:20: In file included from /opt/local/include/boost/iterator/iterator_concepts.hpp:10: /opt/local/include/boost/iterator/iterator_categories.hpp:119:60: error: no type named 'iterator_category' in 'std::__1::iterator_traits&lt;boost::coroutines::pull_coroutine&lt;int&gt;::const_iterator&gt;' typename boost::detail::iterator_traits&lt;Iterator&gt;::iterator_category ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~ /opt/local/include/boost/range/adaptor/strided.hpp:606:26: note: in instantiation of template class 'boost::iterators::iterator_traversal&lt;boost::coroutines::pull_coroutine&lt;int&gt;::const_iterator&gt;' requested here typename iterator_traversal&lt; ^ /opt/local/include/boost/range/adaptor/strided.hpp:660:16: note: in instantiation of default argument for 'strided_range&lt;const boost::coroutines::pull_coroutine&lt;int&gt; &gt;' required here inline strided_range&lt;const Rng&gt; ^~~~~~~~~~~~~~~~~~~~~~~~ 6-concurrency/coroutine.cc:30:24: note: while substituting deduced template arguments into function template 'operator|' [with Rng = boost::coroutines::pull_coroutine&lt;int&gt;, Difference = int] for (auto i : source | strided(10)) ^ In file included from 6-concurrency/coroutine.cc:4: /opt/local/include/boost/range/adaptor/strided.hpp:627:21: error: no matching function for call to 'make_begin_strided_iterator' range_detail::make_begin_strided_iterator( ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /opt/local/include/boost/range/adaptor/strided.hpp:656:20: note: in instantiation of function template specialization 'boost::range_detail::strided_range&lt;boost::coroutines::pull_coroutine&lt;int&gt;, boost::iterators::single_pass_traversal_tag&gt;::strided_range&lt;int&gt;' requested here return strided_range&lt;Rng&gt;(stride.val, rng); ^ 6-concurrency/coroutine.cc:30:24: note: in instantiation of function template specialization 'boost::range_detail::operator|&lt;boost::coroutines::pull_coroutine&lt;int&gt;, int&gt;' requested here for (auto i : source | strided(10)) ^ /opt/local/include/boost/range/adaptor/strided.hpp:412:9: note: candidate function [with Rng = boost::coroutines::pull_coroutine&lt;int&gt;, Difference = int] not viable: no known conversion from 'typename iterator_traversal&lt;typename range_iterator&lt;pull_coroutine&lt;int&gt; &gt;::type&gt;::type' (aka 'boost::iterators::single_pass_traversal_tag') to 'boost::iterators::forward_traversal_tag' for 3rd argument make_begin_strided_iterator( ^ /opt/local/include/boost/range/adaptor/strided.hpp:476:9: note: candidate function [with Rng = boost::coroutines::pull_coroutine&lt;int&gt;, Difference = int] not viable: no known conversion from 'typename iterator_traversal&lt;typename range_iterator&lt;pull_coroutine&lt;int&gt; &gt;::type&gt;::type' (aka 'boost::iterators::single_pass_traversal_tag') to 'boost::iterators::bidirectional_traversal_tag' for 3rd argument make_begin_strided_iterator( ^ /opt/local/include/boost/range/adaptor/strided.hpp:544:9: note: candidate function [with Rng = boost::coroutines::pull_coroutine&lt;int&gt;, Difference = int] not viable: no known conversion from 'typename iterator_traversal&lt;typename range_iterator&lt;pull_coroutine&lt;int&gt; &gt;::type&gt;::type' (aka 'boost::iterators::single_pass_traversal_tag') to 'boost::iterators::random_access_traversal_tag' for 3rd argument make_begin_strided_iterator( ^ /opt/local/include/boost/range/adaptor/strided.hpp:428:9: note: candidate function [with Rng = boost::coroutines::pull_coroutine&lt;int&gt;, Difference = int] not viable: no known conversion from 'typename iterator_traversal&lt;typename range_iterator&lt;pull_coroutine&lt;int&gt; &gt;::type&gt;::type' (aka 'boost::iterators::single_pass_traversal_tag') to 'boost::iterators::forward_traversal_tag' for 3rd argument make_begin_strided_iterator( ^ /opt/local/include/boost/range/adaptor/strided.hpp:494:9: note: candidate function [with Rng = boost::coroutines::pull_coroutine&lt;int&gt;, Difference = int] not viable: no known conversion from 'typename iterator_traversal&lt;typename range_iterator&lt;pull_coroutine&lt;int&gt; &gt;::type&gt;::type' (aka 'boost::iterators::single_pass_traversal_tag') to 'boost::iterators::bidirectional_traversal_tag' for 3rd argument make_begin_strided_iterator( ^ /opt/local/include/boost/range/adaptor/strided.hpp:560:9: note: candidate function [with Rng = boost::coroutines::pull_coroutine&lt;int&gt;, Difference = int] not viable: no known conversion from 'typename iterator_traversal&lt;typename range_iterator&lt;pull_coroutine&lt;int&gt; &gt;::type&gt;::type' (aka 'boost::iterators::single_pass_traversal_tag') to 'boost::iterators::random_access_traversal_tag' for 3rd argument make_begin_strided_iterator( ^ 2 errors generated. make[1]: *** [6-concurrency/coroutine.log] Error 1 make[1]: Leaving directory `/Users/akim/src/lrde/cours/cxxa' make: *** [all] Error 2 Compilation exited abnormally with code 2 at Thu May 7 10:29:24 </pre><p> It seems to me that the problem is that const_iterator does not define iterator_category, and it should. Maybe Boost.Coroutine should use Boost.<a class="missing wiki">IteratorFacade</a> to define its iterators? </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11274 Trac 1.4.3 olli Mon, 11 May 2015 17:46:16 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/11274#comment:1 https://svn.boost.org/trac10/ticket/11274#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> It's a problem of boost.range (1.58): 'Although the doc says <code>strided</code> supports <a class="missing wiki">SinglePassRange</a>, the current implementation of &lt;boost/range/adaptor/strided.hpp&gt; does not support <a class="missing wiki">SinglePassRange</a>; it needs <a class="missing wiki">ForwardRange</a>.' </p> Ticket