I was pretty surprised when I found that the following code actually works:
std::vector<int> list /*= ...*/;
std::tr1::function<void(int)> func = ^(int i) {
return i + 1;
};
std::for_each(list.begin(), list.end(), func);
Seems like std::tr1::function
is capable of being constructed from an Objective-C block, but I'm not sure quite how, since (last I checked), its implementation doesn't specifically handle blocks. Is it somehow implicitly sucking out the underlying function pointer? Also, is this behavior undefined and likely to change?
Update: I was wrong, here's why it really works
std::tr1::function
's template parameter simply defines the signature of the resulting function object, not the type it actually wraps. Thus, the wrapped object only needs to offer an operator()
with matching signature. Block references, like function pointers, have such an operator()
implicitly (obviously, so you can call them).
Old, incorrect answer (so the comments make sense)
I strongly suspect it works because the block doesn't capture any variables from the surrounding scope. In that case, there is no state to maintain, so a block reference can be represented as a bare function pointer. If we change the code to
std::vector<int> list /*= ...*/;
int counter = 0;
std::tr1::function<void(int)> func = ^(int i) {
counter++;
return i + counter;
};
std::for_each(list.begin(), list.end(), func);
it should fail to compile, as the block must carry the captured value of counter
around with it. (unless of course the implementation of std::tr1::function
has been specifically updated to support blocks)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With