[Function] Problem using target() with boost::mem_fn and boost::bind

Hi, I have encountered a crash trying to use the target() function to retrieve a function pointer from a boost.function initialized with a member function (using boost.bind). See the code below. // =========================================== #include <iostream> #include <boost/bind.hpp> #include <boost/function.hpp> typedef double(*FunctionType) (double); double Square( FunctionType f, double x ) { return f(x) * f(x) ; } class A { private: double x_; double y_; public: A() : x_(1.0), y_(1.0) {} double Area(double x, double y) { x_ = x; y_ = y; return x_ * y_; } }; int main() { A a1; boost::function<double(double)> f1 = boost::bind( boost::mem_fn(&A::Area), &a1, _1, 2.5 ); double s1 = f1(2.0); // this works FunctionType f2 = *f1.target<FunctionType>() ; // Error: this would crash s1 = Square( f2, 2.0 ); return 0; } // ====================================================== After debugging the code, I found out that the crashed happened inside target() function in file function_base.hpp: template<typename Functor> Functor* target() { if (!vtable) return 0; detail::function::function_buffer type_result; type_result.const_obj_ptr = &typeid(Functor); vtable->manager(functor, type_result, detail::function::check_functor_type_tag); return static_cast<Functor*>(type_result.obj_ptr); } After vtable->manager() call, type_result became null, and this caused static_cast to fail. I was using boost_1_36_0 precompiled by BoostPro with Visual Studio 2008. Is this an expected behavior? Your feedback would be greatly appreciated. Pengcheng Song -- View this message in context: http://www.nabble.com/-Function--Problem-using-target%28%29-with-boost%3A%3A... Sent from the Boost - Dev mailing list archive at Nabble.com.

On Wed, Dec 3, 2008 at 3:14 PM, Pengcheng Song <pengcheng.simon@gmail.com> wrote: <snip>
A a1; boost::function<double(double)> f1 = boost::bind( boost::mem_fn(&A::Area), &a1, _1, 2.5 ); double s1 = f1(2.0); // this works FunctionType f2 = *f1.target<FunctionType>() ; // Error: this would crash
<snip>
Is this an expected behavior? Your feedback would be greatly appreciated.
Yes, because the type of the wrapped function object is not FunctionType, it's the return type of bind(). (Unfortunately, the return type of bind() is not formally specified.) When boost::function cannot perform the runtime conversion, it returns a null pointer as documented. The crash is actually caused when you dereference this pointer. If you make the following changes, you're code should be safe. FunctionType* f2 = f1.target<FunctionType>() ; // no crash if(f2) s1 = Square( *f2, 2.0 ); Daniel Walker
participants (2)
-
Daniel Walker
-
Pengcheng Song