I've wondered if it is possible to convert a C++0x lambda to a clang block. So far anything I've seen on it has involved the discussion between their differences. My primary reason for looking into this, is to make an eventual wrapper for libdispatch
, and while I'm quite aware of dispatch_*_f
functions, any information on their use has been quite lacking, in comparison to their block counterpart.
So far I've been able to find information on converting a C++ lambda to a function pointer, but this is more in the realm of the reverse.
If anyone knows anything related to this, and could provide a link, or at least point me in the right direction, I would really appreciate it. (even a "This is not currently possible" answer will suffice)
I don't think an actual convert is possible. Unlike the reverse case, getting rid of the original clang block, has some side effects that you can't recover from. While C++0x lambdas can capture variables by reference, nothing special is done to make sure the original variable is still there when you actually intend to use the lambda. Blocks on the other hand, can interact with variables declared with the
__block
storage qualifier, in which case these variables will be kept in memory (even if it means being copied from stack to heap) for as long as that block lives (including copies made byBlock_copy
):Therefore unless you intend to keep the original block around (and thus wrapping rather than converting it), some of its original functionality will be missing as the
__block
variables will be gone.However, I'm no expert on the subjects and would love hearing other opinions :)
Well, Clang doesn't yet support lambdas, and neither does the Apple GCC. FSF GCCs recent enough to support lambdas don't support blocks AFAIK. So the question of conversion between them doesn't yet apply.
Once Clang supports both of these, there may be a way in ObjC++ mode to convert between them.
Generally, when lambda is used for "downward" closure, you can convert a c++ lambda to a clang block by converting:
to:
There is still some subtle differences. Clang's blocks only capture C++ classes by const. I don't know if this includes C++ POD types too.
Finally, if "upward" closure is needed, then the two diverge drastically. Clang's blocks require variables captured to be annotated with
__block
, which the compiler will allocate it on the heap. Whereas, in C++, the way the lambda captures, needs to be decided based on the lifetime of the object.(That is by value making a copy or by reference).Also in C++, copying the closure is handle automatically by the copy-constructor mechanism in C++. However, with clang's block,
Block_copy
andBlock_release
need to be called to handle the copying of the block. A simple wrapper can be written in C++ to handle this. For example:A patch enabling this conversion implicitly was just added to clang trunk.
I recommend using the
*_f
versions of the libdispatch functions. All the block versions are implemented in terms of the function versions under the hood, and it's far easier to write a C++ template that produces a function that calls a lambda object than a template that produces a block that calls a lambda object.However, the current lack of support in Clang for C++ lambdas may throw a damper on the whole thing.