id,summary,reporter,owner,description,type,status,milestone,component,version,severity,resolution,keywords,cc 3840,Boost.Intrusive conflicts with Boost.Bind + smart pointers,Andrey Semashev,Ion Gaztañaga,"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: {{{ #include #include #include namespace intrusive = boost::intrusive; typedef intrusive::list_base_hook< intrusive::link_mode< intrusive::auto_unlink >, intrusive::tag< struct MyStructTag > > 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< MyStruct, intrusive::base_hook< ListHook_t >, intrusive::constant_time_size< false > > List_t; int main(int, char*[]) { List_t structs; boost::intrusive_ptr< MyStruct > p = new MyStruct(); structs.push_back(*p); boost::bind(&MyStruct::foo, p)(); return 0; } }}} The compilation fails at least with MSVC 7.1 and GCC 4.1.0, the error is as follows: {{{ ./ThirdParty/BOOST/boost/intrusive/detail/utilities.hpp: In instantiation of 'boost::intrusive::detail::smart_ptr_type >': ./ThirdParty/BOOST/boost/bind/mem_fn_template.hpp:40: instantiated from 'R boost::_mfi::mf0::call(U&, const void*) const [with U = boost::intrusive_ptr, R = void, T = MyStruct]' ./ThirdParty/BOOST/boost/bind/mem_fn_template.hpp:54: instantiated from 'R boost::_mfi::mf0::operator()(U&) const [with U = boost::intrusive_ptr, R = void, T = MyStruct]' ./ThirdParty/BOOST/boost/bind/bind.hpp:246: instantiated from 'void boost::_bi::list1::operator()(boost::_bi::type, F&, A&, int) [with F = boost::_mfi::mf0, A = boost::_bi::list0, A1 = boost::_bi::value >]' ./ThirdParty/BOOST/boost/bind/bind_template.hpp:20: instantiated from 'typename boost::_bi::result_traits::type boost::_bi::bind_t::operator()() [with R = void, F = boost::_mfi::mf0, L = boost::_bi::list1 > >]' 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' ./ThirdParty/BOOST/boost/intrusive/detail/utilities.hpp:114: error: no type named 'value_type' in 'class boost::intrusive_ptr' ./ThirdParty/BOOST/boost/intrusive/detail/utilities.hpp:115: error: no type named 'value_type' in 'class boost::intrusive_ptr' }}} 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. 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. 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. ",Bugs,closed,Boost 1.45.0,intrusive,Boost 1.41.0,Problem,fixed,get_pointer bind mem_fn intrusive,