Boost C++ Libraries: Ticket #10847: Offset overloads of next() / prior() have stopped compiling for iterators that previously worked https://svn.boost.org/trac10/ticket/10847 <h3 class="section" id="Summary">Summary</h3> <p> In Boost v1.57.0, the offset overloads of <code>boost::next()</code> / <code>boost::prior()</code> have stopped compiling for iterators that previously worked in &lt;= v1.56.0. </p> <p> I think this is because commit 651a869d4f9479dd3dfdd0293305a60b8c8d0e1c (Boost Trac won't let me paste link without passing some non-existent captcha) has replaced a call to <code>std::advance()</code> with a custom approach using type_traits (such as <code>has_plus_assign</code>). </p> <p> Unfortunately some iterators indicate their non-provision of random-access through their iterator category (eg <code>forward_iterator_tag</code>) but provide <code>operator+=</code> and <code>operator+</code> methods/functions that don't compile. </p> <p> Examples: </p> <ul><li>iterators returned by boost::ptr_set and </li><li>iterators returned by GCC's std::list&lt;&gt; when <code>_GLIBCXX_DEBUG</code> is defined </li></ul><p> Importantly, these iterators work without problem under: </p> <ul><li>std::advance(), </li><li>Boost v1.56.0's <code>boost::next()</code> / <code>boost::prior()</code> and </li><li>C++11's <code>std::next()</code> / <code>std::prev()</code> (at least under GCC v4.9.1's implementation) </li></ul><p> ...so Boost v1.57.0 <code>next()</code> / <code>prior()</code> are out of step with the standard (or <code>std::</code>) approach. </p> <h3 class="section" id="Example">Example</h3> <p> Attempting to compile: </p> <pre class="wiki">#include &lt;boost/next_prior.hpp&gt; #include &lt;boost/ptr_container/ptr_set.hpp&gt; #include &lt;iostream&gt; #include &lt;list&gt; int main() { boost::ptr_set&lt;int&gt; the_ptr_set; the_ptr_set.insert( new int( 1 ) ); the_ptr_set.insert( new int( 2 ) ); std::cerr &lt;&lt; *boost::next( the_ptr_set.begin(), 1 ) &lt;&lt; std::endl; std::list&lt;int&gt; the_list; the_list.push_back( 1 ); the_list.push_back( 2 ); std::cerr &lt;&lt; *boost::next( the_list.begin(), 1 ) &lt;&lt; std::endl; return 0; } </pre><p> ...with <code>g++ -D_GLIBCXX_DEBUG -o next_prior_prob next_prior_prob.cpp</code> (GCC v4.9.1) produces the following compiler errors: </p> <pre class="wiki">In file included from /usr/include/c++/4.9/debug/set.h:33:0, from /usr/include/c++/4.9/debug/set:33, from /usr/include/c++/4.9/set:66, from /usr/include/boost/ptr_container/ptr_set.hpp:21, from next_prior_prob.cpp:2: /usr/include/c++/4.9/debug/safe_iterator.h: In instantiation of ‘__gnu_debug::_Safe_iterator&lt;_Iterator, _Sequence&gt;&amp; __gnu_debug::_Safe_iterator&lt;_Iterator, _Sequence&gt;::operator+=(const difference_type&amp;) [with _Iterator = std::__cxx1998::_List_iterator&lt;int&gt;; _Sequence = std::__debug::list&lt;int&gt;; __gnu_debug::_Safe_iterator&lt;_Iterator, _Sequence&gt;::difference_type = int]’: /usr/include/boost/next_prior.hpp:73:11: required from ‘static T boost::next_prior_detail::next_impl1&lt;T, Distance, true&gt;::call(T, Distance) [with T = __gnu_debug::_Safe_iterator&lt;std::__cxx1998::_List_iterator&lt;int&gt;, std::__debug::list&lt;int&gt; &gt;; Distance = int]’ /usr/include/boost/next_prior.hpp:151:67: required from ‘T boost::next(T, Distance) [with T = __gnu_debug::_Safe_iterator&lt;std::__cxx1998::_List_iterator&lt;int&gt;, std::__debug::list&lt;int&gt; &gt;; Distance = int]’ next_prior_prob.cpp:16:49: required from here /usr/include/c++/4.9/debug/safe_iterator.h:357:13: error: no match for ‘operator+=’ (operand types are ‘std::__cxx1998::_List_iterator&lt;int&gt;’ and ‘const difference_type {aka const int}’) _M_current += __n; ^ /usr/include/c++/4.9/debug/safe_iterator.h: In instantiation of ‘__gnu_debug::_Safe_iterator&lt;_Iterator, _Sequence&gt;&amp; __gnu_debug::_Safe_iterator&lt;_Iterator, _Sequence&gt;::operator+=(const difference_type&amp;) [with _Iterator = std::_Rb_tree_const_iterator&lt;void*&gt;; _Sequence = std::__debug::set&lt;void*, boost::void_ptr_indirect_fun&lt;std::less&lt;int&gt;, int, int&gt;, std::allocator&lt;void*&gt; &gt;; __gnu_debug::_Safe_iterator&lt;_Iterator, _Sequence&gt;::difference_type = int]’: /usr/include/boost/ptr_container/detail/void_ptr_iterator.hpp:104:23: required from ‘boost::void_ptr_iterator&lt;VoidIter, T&gt;&amp; boost::void_ptr_iterator&lt;VoidIter, T&gt;::operator+=(boost::void_ptr_iterator&lt;VoidIter, T&gt;::difference_type) [with VoidIter = __gnu_debug::_Safe_iterator&lt;std::_Rb_tree_const_iterator&lt;void*&gt;, std::__debug::set&lt;void*, boost::void_ptr_indirect_fun&lt;std::less&lt;int&gt;, int, int&gt;, std::allocator&lt;void*&gt; &gt; &gt;; T = int; boost::void_ptr_iterator&lt;VoidIter, T&gt;::difference_type = int]’ /usr/include/boost/next_prior.hpp:73:11: required from ‘static T boost::next_prior_detail::next_impl1&lt;T, Distance, true&gt;::call(T, Distance) [with T = boost::void_ptr_iterator&lt;__gnu_debug::_Safe_iterator&lt;std::_Rb_tree_const_iterator&lt;void*&gt;, std::__debug::set&lt;void*, boost::void_ptr_indirect_fun&lt;std::less&lt;int&gt;, int, int&gt;, std::allocator&lt;void*&gt; &gt; &gt;, int&gt;; Distance = int]’ /usr/include/boost/next_prior.hpp:151:67: required from ‘T boost::next(T, Distance) [with T = boost::void_ptr_iterator&lt;__gnu_debug::_Safe_iterator&lt;std::_Rb_tree_const_iterator&lt;void*&gt;, std::__debug::set&lt;void*, boost::void_ptr_indirect_fun&lt;std::less&lt;int&gt;, int, int&gt;, std::allocator&lt;void*&gt; &gt; &gt;, int&gt;; Distance = int]’ next_prior_prob.cpp:11:52: required from here /usr/include/c++/4.9/debug/safe_iterator.h:357:13: error: no match for ‘operator+=’ (operand types are ‘std::_Rb_tree_const_iterator&lt;void*&gt;’ and ‘const difference_type {aka const int}’) </pre><p> (but has no problems if <code>boost::next()</code> is replaced with <code>std::next()</code> and <code>-std=c++11</code> is used) </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/10847 Trac 1.4.3 ivan.lelann@… Tue, 30 Jun 2015 13:10:44 GMT <link>https://svn.boost.org/trac10/ticket/10847#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/10847#comment:1</guid> <description> <p> For the same reason, boost::next is broken with std::reverse_iterator (tested with GCC libstdc++ 5.1) </p> <pre class="wiki">#include &lt;list&gt; #include &lt;vector&gt; #include &lt;iostream&gt; #include &lt;boost/utility.hpp&gt; int main() { std::list&lt;int&gt; ints {1,2,3,4,5,6,7}; // begin/end OK with boost::next or std::next std::cout &lt;&lt; *(std::next(begin(ints), 2)) &lt;&lt; std::endl; std::cout &lt;&lt; *(std::next(end(ints), -2)) &lt;&lt; std::endl; std::cout &lt;&lt; *(boost::next(begin(ints), 2)) &lt;&lt; std::endl; std::cout &lt;&lt; *(boost::next(end(ints), -2)) &lt;&lt; std::endl; // rbegin/rend KO with boost::next std::cout &lt;&lt; *(std::next(rbegin(ints), 2)) &lt;&lt; std::endl; std::cout &lt;&lt; *(std::next(rend(ints), -2)) &lt;&lt; std::endl; // KO std::cout &lt;&lt; *(boost::next(rbegin(ints), 2)) &lt;&lt; std::endl; std::cout &lt;&lt; *(boost::next(rend(ints), -2)) &lt;&lt; std::endl; } </pre> </description> <category>Ticket</category> </item> <item> <author>raad@…</author> <pubDate>Tue, 07 Jul 2015 04:39:14 GMT</pubDate> <title>cc set https://svn.boost.org/trac10/ticket/10847#comment:2 https://svn.boost.org/trac10/ticket/10847#comment:2 <ul> <li><strong>cc</strong> <span class="trac-author">raad@…</span> added </li> </ul> Ticket Andrey Semashev Tue, 07 Jul 2015 07:48:15 GMT cc changed https://svn.boost.org/trac10/ticket/10847#comment:3 https://svn.boost.org/trac10/ticket/10847#comment:3 <ul> <li><strong>cc</strong> <span class="trac-author">Andrey.Semashev@…</span> added </li> </ul> Ticket Andrey Semashev Sun, 09 Jul 2017 10:54:17 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/10847#comment:4 https://svn.boost.org/trac10/ticket/10847#comment:4 <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">fixed</span> </li> </ul> <p> Should be fixed in <a class="ext-link" href="https://github.com/boostorg/utility/commit/6cf9c22cf159e74945b2b2e5a5170fd5bb56a54f"><span class="icon">​</span>https://github.com/boostorg/utility/commit/6cf9c22cf159e74945b2b2e5a5170fd5bb56a54f</a>. </p> Ticket