Edit: After discussing this answer a bit (with Charles Bailey), I find this unsafe as it depends on the implementation of the boost :: function.
The table of calls when entering actual_foo will look something like this:
actual_foo boost::function::operator() main
So, when actual_foo has finished executing, we will return to the operator() boost::function code, and this object has been deleted. This is not a problem - it is a bit like calling delete this , but you have to be very careful what you do in the member function of the remote object. You cannot name any virtual functions or use any data items.
The problem is that I don't know that boost::function makes any guarantees as to what it does in operator() after the function that it wraps has been called. It seems that on my platform this does nothing dangerous (therefore valgrind does not complain), but it is quite possible that on another platform, with a different implementation or with different compilation flags, you might want to do something that is not allowed only after uninstallation object - for example, it can write out some debugging information using a member variable.
Thus, I believe this is a dangerous thing that can lead to undefined behavior under certain circumstances.
Further note:
I quickly looked at what the promotion actually does after calling the function. Looking here: http://boost.cvs.sourceforge.net/viewvc/boost/boost/boost/function/function_template.hpp?view=markup in the operator () function on line 687, my interpretation is that it immediately returns the return value and does not do anything else, so in practice, with this implementation, you should be fine, but comments about it are dangerous. Please note that I could very well find the wrong bit of code and / or misunderstood it ...
Original answer below:
I believe that everything is in order. By the time actual_foo boost::bind and boost::function objects have completed their tasks, and you are executing the actual actual_foo function.
I tested this on my platform (gcc 4.2.4, Linux) by running the program through valgrind .
Here is the program that I ran:
#include <boost/bind.hpp> #include <boost/function.hpp> class Magic { public: int magic( int i ) { return 5; } }; typedef boost::function<int(int)> foo_type; foo_type* global_foo = NULL; int actual_foo( int i, Magic* m ) { delete global_foo; return m->magic(i); } int main() { Magic m; global_foo = new foo_type( boost::bind( &actual_foo, _1, &m ) ); return (*global_foo)(10); }
and here is the output of valgrind:
$ valgrind ./boost_bind ==17606== Memcheck, a memory error detector. ==17606== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al. ==17606== Using LibVEX rev 1804, a library for dynamic binary translation. ==17606== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP. ==17606== Using valgrind-3.3.0-Debian, a dynamic binary instrumentation framework. ==17606== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al. ==17606== For more details, rerun with: -v ==17606== ==17606== ==17606== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 1) ==17606== malloc/free: in use at exit: 0 bytes in 0 blocks. ==17606== malloc/free: 1 allocs, 1 frees, 16 bytes allocated. ==17606== For counts of detected errors, rerun with: -v ==17606== All heap blocks were freed
I have to say that this seems like a strange thing. I would prefer, if possible, to use automatic deletion of this functional object by making it a stack variable or by deleting it in the stack variable destructor (as in RAII ). It would be more neat, safer, less scary and safer. But I am sure that you already know all this, and there are good reasons for living with the code as it is.