Boost C++ Libraries: Ticket #6373: transform_iterator not preserving bidirectionality of std::map iterator https://svn.boost.org/trac10/ticket/6373 <p> Using transform_iterator on std::map iterator does not seem to preserve bidirectionality. </p> <div class="wiki-code"><div class="code"><pre><span class="n">map</span><span class="o">::</span><span class="n">iterator</span> <span class="n">itend</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">end</span><span class="p">();</span> <span class="n">XIt</span> <span class="n">xend</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">make_transform_iterator</span><span class="p">(</span><span class="n">itend</span><span class="p">,</span><span class="n">xfunc</span><span class="p">());</span> <span class="n">XIt</span> <span class="n">xlast</span> <span class="o">=</span> <span class="n">xend</span><span class="p">;</span> <span class="o">--</span><span class="n">xlast</span><span class="p">;</span> <span class="n">assert</span><span class="p">(</span><span class="n">xend</span> <span class="o">!=</span> <span class="n">xlast</span><span class="p">);</span> <span class="c1">// succeeds !</span> <span class="n">xlast</span> <span class="o">=</span> <span class="n">xend</span><span class="p">;</span> <span class="n">std</span><span class="o">::</span><span class="n">advance</span><span class="p">(</span><span class="n">xlast</span><span class="p">,</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="n">assert</span><span class="p">(</span><span class="n">xend</span> <span class="o">!=</span> <span class="n">xlast</span><span class="p">);</span> <span class="c1">// fails !</span> </pre></div></div><p> See also <a class="ext-link" href="http://stackoverflow.com/questions/8783048/bidirectional-boost-transform-iterator-as-with-stdmap"><span class="icon">​</span>StackOverflow Issue 8783048</a> for longer (compilable) example. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/6373 Trac 1.4.3 jeffrey.hellrung Mon, 08 Oct 2012 03:56:34 GMT <link>https://svn.boost.org/trac10/ticket/6373#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/6373#comment:1</guid> <description> <p> Actually there's a couple things going on here. At least for the referenced <a class="missing wiki">StackOverflow</a> question, the poster is "lying" about the result of XFunc. The correct way to define XFunc is as </p> <div class="wiki-code"><div class="code"><pre><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">Pt</span><span class="o">&gt;</span> <span class="k">struct</span> <span class="n">XFunc</span> <span class="p">{</span> <span class="k">typedef</span> <span class="k">typename</span> <span class="n">Pt</span><span class="o">::</span><span class="n">first_type</span> <span class="o">&amp;</span> <span class="n">result_type</span><span class="p">;</span> <span class="n">result_type</span> <span class="nf">operator</span><span class="p">()(</span><span class="k">const</span> <span class="n">Pt</span> <span class="o">&amp;</span><span class="n">p</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">p</span><span class="p">.</span><span class="n">first</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> </pre></div></div><p> and then the example code works. </p> <p> However, more fundamentally, if your composition function does *not* return a genuine C++ reference (which was what was being told to transform_iterator prior to the above change), there's not a whole lot iterator_facade can do strictly within the constraints of the C++ standard: ISO/IEC 14882:2003(E) 24.1.3 describes the requirements of Forward iterators (of which Bidirectional iterators are a refinement), and the relevant requirement in this case is that "*a" returns a genuine C++ reference (not a proxy reference, not by-value). This is (IMHO) a deficiency in the STL categorization of iterators, hence the rationale for Boost's separate traversal and access tags. </p> <p> The immediate workaround is to override transform_iterator's deduction mechanism for the iterator_category typedef by explicitly providing it. A more long-term workaround is to drum up support within the C++ community for a change in the standard wording and/or support within the Boost community for a change in the behavior of iterator_facade to conform more to "common sense" than to the strict word of the standard. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>jeffrey.hellrung</dc:creator> <pubDate>Mon, 08 Oct 2012 04:02:19 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/6373#comment:2 https://svn.boost.org/trac10/ticket/6373#comment:2 <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">wontfix</span> </li> </ul> Ticket