Boost C++ Libraries: Ticket #4967: apply_visitor_delayed_t 's operator() is not const correct https://svn.boost.org/trac10/ticket/4967 <p> The operator() overload in Boost.Variant's boost::apply_visitor_delayed_t is not const qualified which I think could be safely add. </p> <p> The benefit of adding const is as following: </p> <p> There are some generic function need to store and call the apply_visitor_delayed_t instance, transform_iterator &amp; transform_range, for example. The following code will not compile without the const quality: </p> <hr /> <p> using namespace boost; using namespace std; </p> <p> typedef variant&lt;int, string&gt; V; </p> <p> struct times_2_t : public static_visitor&lt;int&gt; { </p> <blockquote> <p> template&lt;class T&gt; int operator()(T const&amp; t) const { </p> <blockquote> <p> return 2 * t; </p> </blockquote> <p> }; </p> </blockquote> <blockquote> <p> int operator()(string const&amp; s) const { </p> <blockquote> <p> return 2 * s.size(); </p> </blockquote> <p> }; </p> </blockquote> <p> }; </p> <p> BOOST_AUTO_TEST_CASE(Test) { </p> <blockquote> <p> vector&lt;V&gt; all; all.push_back(1); all.push_back(2); </p> </blockquote> <p> </p> <blockquote> <p> times_2_t times_2; int const result = boost::accumulate( </p> <blockquote> <p> all | boost::adaptors::transformed(apply_visitor(times_2)), 0); </p> </blockquote> </blockquote> <blockquote> <p> BOOST_CHECK_EQUAL(6, result); </p> </blockquote> <p> } </p> <hr /> <p> One way to fix this is using a boost::funciton to hold the apply_visitor_delayed_t instance and pass the wrapper to transformed: </p> <hr /> <blockquote> <p> times_2_t times_2; function&lt;int(V const&amp;)&gt; f = apply_visitor(times_2); int const result = boost::accumulate( </p> <blockquote> <p> all | boost::adaptors::transformed(apply_visitor(f)), 0); </p> </blockquote> </blockquote> <hr /> <p> However, this will make simple things complex and have runtime cost. </p> <p> So a more direct fix would be add the harmless const qualify to the operator() for apply_visitor_delayed_t </p> <p> The attached is a simply patch: </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/4967 Trac 1.4.3 anonymous Wed, 08 Dec 2010 16:24:56 GMT attachment set https://svn.boost.org/trac10/ticket/4967 https://svn.boost.org/trac10/ticket/4967 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">patch.diff</span> </li> </ul> <p> The patch for adding the harmless const qualify for the apply_visitor_delayed_t </p> Ticket anonymous Wed, 08 Dec 2010 16:39:39 GMT <link>https://svn.boost.org/trac10/ticket/4967#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4967#comment:1</guid> <description> <p> The second code snipper should be this: </p> <div class="wiki-code"><div class="code"><pre> <span class="n">times_2_t</span> <span class="n">times_2</span><span class="p">;</span> <span class="n">function</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">(</span><span class="n">V</span> <span class="k">const</span><span class="o">&amp;</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">f</span> <span class="o">=</span> <span class="n">apply_visitor</span><span class="p">(</span><span class="n">times_2</span><span class="p">);</span> <span class="kt">int</span> <span class="k">const</span> <span class="n">result</span> <span class="o">=</span> <span class="n">boost</span><span class="o">::</span><span class="n">accumulate</span><span class="p">(</span> <span class="n">all</span> <span class="o">|</span> <span class="n">boost</span><span class="o">::</span><span class="n">adaptors</span><span class="o">::</span><span class="n">transformed</span><span class="p">(</span><span class="n">f</span><span class="p">),</span> <span class="mi">0</span><span class="p">);</span> </pre></div></div> </description> <category>Ticket</category> </item> <item> <dc:creator>Steven Watanabe</dc:creator> <pubDate>Wed, 08 Dec 2010 17:28:45 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4967#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4967#comment:2</guid> <description> <p> Simply making the overloads const is not harmless, because it will break code that uses function objects that aren't const. The right way is to add const overloads. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Steven Watanabe</dc:creator> <pubDate>Wed, 08 Dec 2010 17:30:55 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/4967#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/4967#comment:3</guid> <description> <p> Never mind. I'm obviously not looking at the code carefully enough. </p> </description> <category>Ticket</category> </item> <item> <author>prabhu.swain@…</author> <pubDate>Mon, 13 Dec 2010 10:02:55 GMT</pubDate> <title>cc set https://svn.boost.org/trac10/ticket/4967#comment:4 https://svn.boost.org/trac10/ticket/4967#comment:4 <ul> <li><strong>cc</strong> <span class="trac-author">prabhu.swain@…</span> added </li> </ul> Ticket Steven Watanabe Mon, 03 Jan 2011 05:06:55 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/4967#comment:5 https://svn.boost.org/trac10/ticket/4967#comment:5 <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> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/67605" title="Make operator() const. Fixes #4967">[67605]</a>) Make operator() const. Fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/4967" title="#4967: Patches: apply_visitor_delayed_t 's operator() is not const correct (closed: fixed)">#4967</a> </p> Ticket