Boost C++ Libraries: Ticket #4647: BOOST_CONCEPT_ASSERT((RandomAccessIterator<boost::transform_iterator>)) fails https://svn.boost.org/trac10/ticket/4647 <div class="wiki-code"><div class="code"><pre><span class="cp">#include</span> <span class="cpf">&lt;boost/iterator/transform_iterator.hpp&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/concept_check.hpp&gt; // RandomAccessIterator</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp"></span> <span class="k">typedef</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;::</span><span class="n">iterator</span> <span class="n">int_iterator</span><span class="p">;</span> <span class="k">typedef</span> <span class="n">boost</span><span class="o">::</span><span class="n">transform_iterator</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">int</span><span class="p">),</span> <span class="n">int_iterator</span><span class="o">&gt;</span> <span class="n">tr_iterator</span><span class="p">;</span> <span class="n">BOOST_CONCEPT_ASSERT</span><span class="p">((</span><span class="n">boost</span><span class="o">::</span><span class="n">RandomAccessIterator</span><span class="o">&lt;</span><span class="n">tr_iterator</span><span class="o">&gt;</span><span class="p">));</span> <span class="c1">// fails</span> </pre></div></div><p> with an error like this: </p> <p> libs/boost-lib/boost/concept_check.hpp: In destructor 'boost::Convertible&lt;X, Y&gt;::~Convertible() [with X = boost::detail::iterator_category_with_traversal&lt;std::input_iterator_tag, boost::random_access_traversal_tag&gt;, Y = std::random_access_iterator_tag]': libs/boost-lib/boost/concept/detail/general.hpp:38: instantiated from 'static void boost::concepts::requirement&lt;boost::concepts::failed************ Model::************&gt;::failed() [with Model = boost::Convertible&lt;boost::detail::iterator_category_with_traversal&lt;std::input_iterator_tag, boost::random_access_traversal_tag&gt;, std::random_access_iterator_tag&gt;]' libs/boost-lib/boost/concept_check.hpp:566: instantiated from 'boost::<a class="missing wiki">RandomAccessIterator</a>&lt;TT&gt;::~<a class="missing wiki">RandomAccessIterator</a>() [with TT = boost::transform_iterator&lt;int (*)(int), <span class="underline">gnu_cxx::</span>normal_iterator&lt;int*, std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;, boost::use_default, boost::use_default&gt;]' libs/boost-lib/boost/concept/detail/general.hpp:38: instantiated from 'static void boost::concepts::requirement&lt;boost::concepts::failed************ Model::************&gt;::failed() [with Model = boost::<a class="missing wiki">RandomAccessIterator</a>&lt;boost::transform_iterator&lt;int (*)(int), __gnu_cxx::__normal_iterator&lt;int*, std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;, boost::use_default, boost::use_default&gt; &gt;]' src/mlib/tests/test_iterator.cpp:123: instantiated from here libs/boost-lib/boost/concept_check.hpp:207: error: conversion from 'boost::detail::iterator_category_with_traversal&lt;std::input_iterator_tag, boost::random_access_traversal_tag&gt;' to non-scalar type 'std::random_access_iterator_tag' requested </p> <p> This is because iterator_adaptor turns std::random_access_iterator_tag into boost::random_access_traversal_tag, then iterator_facade turns it into iterator_category_with_traversal&lt;std::input_iterator_tag, boost::random_access_traversal_tag&gt;. The check fails if </p> <div class="wiki-code"><div class="code"><pre><span class="k">typedef</span> <span class="n">boost</span><span class="o">::</span><span class="n">transform_iterator</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">int</span><span class="p">),</span> <span class="n">int_iterator</span><span class="o">&gt;</span> <span class="n">tr_iterator</span><span class="p">;</span> </pre></div></div><p> but not if </p> <div class="wiki-code"><div class="code"><pre><span class="k">typedef</span> <span class="n">boost</span><span class="o">::</span><span class="n">transform_iterator</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&amp;</span><span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">int</span><span class="p">),</span> <span class="n">int_iterator</span><span class="o">&gt;</span> <span class="n">tr_iterator</span><span class="p">;</span> </pre></div></div><p> Why it matters for me: I try to use "any_iterator", which has two versions, <a class="ext-link" href="http://thbecker.net/free_software_utilities/type_erasure_for_cpp_iterators/start_page.html"><span class="icon">​</span>http://thbecker.net/free_software_utilities/type_erasure_for_cpp_iterators/start_page.html</a> (Thomas Becker's) and <a class="ext-link" href="http://stlab.adobe.com/classadobe_1_1any__iterator.html"><span class="icon">​</span>http://stlab.adobe.com/classadobe_1_1any__iterator.html</a> (Adobe's). The first one do many efforts to avoid this bug but still check iterators for compatibility (see traversal_types_erasure_compatible&lt;&gt;), the second just fails with an error like this. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/4647 Trac 1.4.3 Steven Watanabe Mon, 13 Sep 2010 22:55:22 GMT status, component changed; resolution set https://svn.boost.org/trac10/ticket/4647#comment:1 https://svn.boost.org/trac10/ticket/4647#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> <li><strong>component</strong> <span class="trac-field-old">None</span> → <span class="trac-field-new">iterator</span> </li> </ul> <p> Replying to <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4647" title="#4647: Bugs: BOOST_CONCEPT_ASSERT((RandomAccessIterator&lt;boost::transform_iterator&gt;)) ... (closed: invalid)">Ilya Murav'jov &lt;muravev@…&gt;</a>: </p> <blockquote class="citation"> <div class="wiki-code"><div class="code"><pre><span class="n">This</span> <span class="n">is</span> <span class="n">because</span> <span class="n">iterator_adaptor</span> <span class="n">turns</span> <span class="n">std</span><span class="o">::</span><span class="n">random_access_iterator_tag</span> <span class="n">into</span> <span class="n">boost</span><span class="o">::</span><span class="n">random_access_traversal_tag</span><span class="p">,</span> <span class="n">then</span> <span class="n">iterator_facade</span> <span class="n">turns</span> <span class="n">it</span> <span class="n">into</span> <span class="n">iterator_category_with_traversal</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">input_iterator_tag</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">random_access_traversal_tag</span><span class="o">&gt;</span><span class="p">.</span> <span class="n">The</span> <span class="n">check</span> <span class="n">fails</span> <span class="k">if</span> <span class="k">typedef</span> <span class="n">boost</span><span class="o">::</span><span class="n">transform_iterator</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">int</span><span class="p">),</span> <span class="n">int_iterator</span><span class="o">&gt;</span> <span class="n">tr_iterator</span><span class="p">;</span> <span class="n">but</span> <span class="n">not</span> <span class="k">if</span> <span class="k">typedef</span> <span class="n">boost</span><span class="o">::</span><span class="n">transform_iterator</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&amp;</span><span class="p">(</span><span class="o">*</span><span class="p">)(</span><span class="kt">int</span><span class="p">),</span> <span class="n">int_iterator</span><span class="o">&gt;</span> <span class="n">tr_iterator</span><span class="p">;</span> </pre></div></div></blockquote> <p> This is the correct behavior because of the way the standard defines RandomAccessIterators. </p> Ticket