Boost C++ Libraries: Ticket #9668: insert_check and callees should pass KeyValueCompare by const reference https://svn.boost.org/trac10/ticket/9668 <p> <strong>boost::intrusive::set::insert_check</strong> passes <em><a class="missing wiki">KeyValueCompare</a></em> by value. And then it makes another copy when it passes it by value to the underlying tree_type. As <em><a class="missing wiki">KeyValueCompare</a></em> could be expensive to copy, it seems needless to pass it by value. It should be passed by const reference. This applies to all containers with <em>insert_check</em>. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9668 Trac 1.4.3 vinnie.falco@… Sat, 15 Feb 2014 00:14:57 GMT <link>https://svn.boost.org/trac10/ticket/9668#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9668#comment:1</guid> <description> <p> It looks like this is applicable to any member function that has a template parameter <strong><a class="missing wiki">KeyValueCompare</a></strong>, like <strong>find</strong>. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Sat, 15 Feb 2014 10:15:57 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/9668#comment:2 https://svn.boost.org/trac10/ticket/9668#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">invalid</span> </li> </ul> <p> Thanks for the report. You can always wrap your function objects with a type that holds a reference to your heavyweight function object. Passing by const-reference forces operator() to be const which is not required right now (and thus, this is backwards incompatible). For other function objects used in Intrusive, like cloners and disposers, non-const operator() is very useful to recycle nodes. </p> <p> Usually function in the C++ standard algorithms predicates are passed as values for very good reasons: </p> <p> <a class="ext-link" href="http://stackoverflow.com/questions/8196345/passing-functor-object-by-value-vs-by-reference-c"><span class="icon">​</span>http://stackoverflow.com/questions/8196345/passing-functor-object-by-value-vs-by-reference-c</a> </p> <p> I think you can always obtain the desired performance with a little wrapper. Passing by value is the intended behavior in Intrusive. Maybe not optimal in some cases, but this is by design. </p> Ticket vinnie.falco@… Sat, 15 Feb 2014 17:16:02 GMT <link>https://svn.boost.org/trac10/ticket/9668#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9668#comment:3</guid> <description> <p> That's a fair point, and one that I hadn't considered. Changing my calls to insert_commit to use std::ref() for the functor solved the problem. </p> <p> The reason that I brought it up is because there is a certain asymmetry in the API. When you construct a container with a custom Compare object and initialize it in the constructor, it because a data member of the container and is never copied when used in functions like the find() overloads which do not take an additional <a class="missing wiki">KeyValueCompare</a> parameter. Compare this with the signatures of the overloads which do take the <a class="missing wiki">KeyValueCompare</a> by value. </p> <p> However, this asymmetry is the lesser of the evils, especially since the reference wrapper is a very acceptible workaround. Thanks </p> </description> <category>Ticket</category> </item> </channel> </rss>