The following code throws an exception
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::bad_function_call> >'
what(): call to empty boost::function
at the line f()
(while executing the block):
void foo(); // assume this is defined somewhere
boost::function<void()> f = boost::bind(&foo);
^(void) {
f();
}();
However, according to the documentation on blocks,
In general you can use C++ objects within a block. Within a member function, references to member variables and functions are via an implicitly imported this pointer and thus appear mutable. There are two considerations that apply if a block is copied:
If you have a __block storage class for what would have been a stack-based C++ object, then the usual copy constructor is used.
If you use any other C++ stack-based object from within a block, it must have a const copy constructor. The C++ object is then copied using that constructor.
This seems to be true normally; if I replace f
above with an instance of a simple class with an operator()()
, the above code runs as expected.
Why doesn't the version with boost::function
work?
It appears that if I modify the declaration with __block
, it works correctly:
__block boost::function<void()> f = boost::bind(&foo);
I'm still not sure why this is - as @Richard mentions in a comment above, it must have to do with the "const copy constructor" as opposed to the "usual copy constructor". I don't know how to check this difference, though; the following works fine:
const boost::function<void()> f = boost::bind(&foo);
const boost::function<void()> g(f);
g();
and if that doesn't call a "const copy constructor", I'm not sure what will.