So, I just upgraded to Xcode 4.4, and I noticed in the changelog:
Apple LLVM compiler supports additional C++11 features, including lambdas
Which is awesome! So I got around to coding, and I found a few things out:
Lambdas are assignable to Objective-C blocks:
void (^block)() = []() -> void {
NSLog(@"Inside Lambda called as block!");
};
block();
std::function
can hold an Objective-C block:
std::function<void(void)> func = ^{
NSLog(@"Block inside std::function");
};
func();
We cant assign an Objective-C block to a lambda:
auto lambda = []() -> {
NSLog(@"Lambda!");
};
lambda = ^{ // error!
NSLog(@"Block!");
};
lambda();
Why is this? Shouldn't the two be semantically equivalent, given what we've seen above?
C++11's lambda's copy-assignment operator is explicitly disabled1. This is not a matter of "semantically equivalent". It can't even assign back to itself. Not to mention an unrelated type.
#include <cstdio>
#include <type_traits>
int main() {
auto lambda1 = []() -> void { printf("Lambda 1!\n"); };
lambda1 = lambda1; // error: use of deleted function ‘main()::<lambda()>& main()::<lambda()>::operator=(const main()::<lambda()>&)’
return 0;
}
std::function
can hold an Objective-C block.
std::function
can hold any types which can be invoked as f(a,b,c,...)
. Since blocks support "the invoke operator", it can also be held by a std::function
. But notice that Objective-C and C++ follow different memory management scheme, so storing a block in a std::function
for a long time may cause dangling reference. Lambdas are assignable to Objective-C blocks:
1: C++11 §5.1.2/19:
The closure type associated with a lambda-expression has a deleted (8.4.3) default constructor and a deleted copy assignment operator.
2: http://llvm.org/viewvc/llvm-project?view=rev&revision=150620
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