Search code examples
c++objective-cblockobjective-c++boost-function

Why can't I use a boost::function in an Objective-C++ block?


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?


Solution

  • 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.