Boost C++ Libraries: Ticket #3840: Boost.Intrusive conflicts with Boost.Bind + smart pointers https://svn.boost.org/trac10/ticket/3840 <p> The file intrusive/detail/utilities.hpp defines generic get_pointer function. Apparently, this function is in conflict with the same-named functions for smart pointers, such as intrusive_ptr, which breaks compilation of boost::bind. The following example shows the problem: </p> <pre class="wiki">#include &lt;boost/bind.hpp&gt; #include &lt;boost/intrusive_ptr.hpp&gt; #include &lt;boost/intrusive/list.hpp&gt; namespace intrusive = boost::intrusive; typedef intrusive::list_base_hook&lt; intrusive::link_mode&lt; intrusive::auto_unlink &gt;, intrusive::tag&lt; struct MyStructTag &gt; &gt; ListHook_t; struct MyStruct : public ListHook_t { void foo() {} friend void intrusive_ptr_add_ref(MyStruct*) {} friend void intrusive_ptr_release(MyStruct*) {} }; typedef intrusive::list&lt; MyStruct, intrusive::base_hook&lt; ListHook_t &gt;, intrusive::constant_time_size&lt; false &gt; &gt; List_t; int main(int, char*[]) { List_t structs; boost::intrusive_ptr&lt; MyStruct &gt; p = new MyStruct(); structs.push_back(*p); boost::bind(&amp;MyStruct::foo, p)(); return 0; } </pre><p> The compilation fails at least with MSVC 7.1 and GCC 4.1.0, the error is as follows: </p> <pre class="wiki">./ThirdParty/BOOST/boost/intrusive/detail/utilities.hpp: In instantiation of 'boost::intrusive::detail::smart_ptr_type&lt;boost::intrusive_ptr&lt;MyStruct&gt; &gt;': ./ThirdParty/BOOST/boost/bind/mem_fn_template.hpp:40: instantiated from 'R boost::_mfi::mf0&lt;R, T&gt;::call(U&amp;, const void*) const [with U = boost::intrusive_ptr&lt;MyStruct&gt;, R = void, T = MyStruct]' ./ThirdParty/BOOST/boost/bind/mem_fn_template.hpp:54: instantiated from 'R boost::_mfi::mf0&lt;R, T&gt;::operator()(U&amp;) const [with U = boost::intrusive_ptr&lt;MyStruct&gt;, R = void, T = MyStruct]' ./ThirdParty/BOOST/boost/bind/bind.hpp:246: instantiated from 'void boost::_bi::list1&lt;A1&gt;::operator()(boost::_bi::type&lt;void&gt;, F&amp;, A&amp;, int) [with F = boost::_mfi::mf0&lt;void, MyStruct&gt;, A = boost::_bi::list0, A1 = boost::_bi::value&lt;boost::intrusive_ptr&lt;MyStruct&gt; &gt;]' ./ThirdParty/BOOST/boost/bind/bind_template.hpp:20: instantiated from 'typename boost::_bi::result_traits&lt;R, F&gt;::type boost::_bi::bind_t&lt;R, F, L&gt;::operator()() [with R = void, F = boost::_mfi::mf0&lt;void, MyStruct&gt;, L = boost::_bi::list1&lt;boost::_bi::value&lt;boost::intrusive_ptr&lt;MyStruct&gt; &gt; &gt;]' 1.cpp:33: instantiated from here ./ThirdParty/BOOST/boost/intrusive/detail/utilities.hpp:113: error: no type named 'value_type' in 'class boost::intrusive_ptr&lt;MyStruct&gt;' ./ThirdParty/BOOST/boost/intrusive/detail/utilities.hpp:114: error: no type named 'value_type' in 'class boost::intrusive_ptr&lt;MyStruct&gt;' ./ThirdParty/BOOST/boost/intrusive/detail/utilities.hpp:115: error: no type named 'value_type' in 'class boost::intrusive_ptr&lt;MyStruct&gt;' </pre><p> One side of the problem is that smart_ptr_type trait, which is used by get_pointer from Boost.Intrusive, incorrectly detects pointee type. It assumes the smart pointer has a value_type nested typedef, while the conventional typedef is element_type. I would suggest using pointee trait from pointee.hpp to get this type portably. </p> <p> The other side of the problem is that get_pointer from Boost.Intrusive should not have been used by Boost.Bind in the first place, because it's defined in the private namespace boost::intrusive::detail. I guess, this happens because of some ADL-related problem. Perhaps there is a using directive somewhere that leads to this. </p> <p> One possible solution of the problem is to simply remove get_pointer definition from Boost.Intrusive and use unqualified calls to get_pointer instead. The version of get_pointer for raw pointers is already available in the get_pointer.hpp header. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3840 Trac 1.4.3 Andrey Semashev Thu, 14 Jan 2010 15:42:54 GMT <link>https://svn.boost.org/trac10/ticket/3840#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3840#comment:1</guid> <description> <p> As my local way of fixing the problem, I renamed the get_pointer from Boost.Intrusive and all references to it. Please, find the patch attached. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Andrey Semashev</dc:creator> <pubDate>Thu, 14 Jan 2010 15:43:42 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/3840 https://svn.boost.org/trac10/ticket/3840 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">get_ptr_fix.patch</span> </li> </ul> <p> The patch renames get_pointer function from Boost.Intrusive </p> Ticket Andrey Semashev Thu, 14 Jan 2010 16:22:35 GMT <link>https://svn.boost.org/trac10/ticket/3840#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3840#comment:2</guid> <description> <p> Oh, I think I know why get_pointer from Boost.Intrusive was found. ListHook_t in my example derives from detail::generic_hook, which brings in the detail namespace into lookup. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Steven Watanabe</dc:creator> <pubDate>Sat, 27 Feb 2010 01:03:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3840#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3840#comment:3</guid> <description> <p> I generally use compile-fail test cases like [source:/trunk/libs/units/test/fail_adl_detail.cpp@46171 fail_adl_detail.cpp] to make sure that ADL isn't going awry. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Ion Gaztañaga</dc:creator> <pubDate>Thu, 26 Aug 2010 10:11:09 GMT</pubDate> <title>status, milestone changed; resolution set https://svn.boost.org/trac10/ticket/3840#comment:4 https://svn.boost.org/trac10/ticket/3840#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> <li><strong>milestone</strong> <span class="trac-field-old">Boost 1.42.0</span> → <span class="trac-field-new">Boost-1.45.0</span> </li> </ul> <p> Fixed for Boost 1.45 in release branch </p> Ticket