Re: Blocks vs. C++ lambda's?
On 30 Apr., 21:40, Boris Du?ek <boris.du...@gmail.com> wrote:
I learned about the blocks feature Apple is implementing as an
extension to C. After looking at it briefly, I concluded it's
Here's a link to a "blocks" specification:
http://clang.llvm.org/docs/BlockLanguageSpec.txt
basically the same thing as C++(0x) lambdas. But there should be a
difference since if not, (I guess) it would make sense to just adopt
the C++ lambda syntax in C and Obj-C to achieve the goal. So could
someone please point out what blocks provide that C++ lambdas do not
(and vice versa)?
It seems they're similar but the "blocks" feature is more tailored to
C while the C++ lambda feature is more tailored to C++.
The C++ lambda syntax doesn't include a special class of nameable
types that can be used to store or refer to C++ lambda objects. But
you need something like this in order to pass those objects/references
around in C (i.e. call a function with a block as parameter). In C++
you don't need a special class of types for this. Lambda objects are
simply objects of some anonymous type which overrides the function
call operator. If you intent to use this object as parameter to
another function you have a choice between
(1) making the function a template so it can accept the lambda
objects directly (no indirection, inlining possible)
(2) making the function accept a parameter of some function<>
instance (indirection, no inlining possible)
Feature-wise, I think C++ lambdas are more powerful. You can easily
emulate "C blocks" with C++ lambdas wrapped in a polymorphic
function<> object. So, the C++ lambdas are more like a low level
feature whereas "C blocks" are a high level feature which includes
implicit memory and life-time management. To emulate this in C++0x you
could use a shared_ptr which is captured by value and refers to the
"__block" data. So, the following C code with "clang blocks"
// may store block for later use
void bar( int(^blk)(int) );
void foo() {
__block int x;
int factor;
x = 23;
factor = 3;
bar(^(int a){return x += a*factor;});
}
could be translated to this C++0x version
// may store function object for later use
void bar(function<int()> blk);
void foo() {
shared_ptr<int> px (new int);
*px = 23;
int factor = 3;
bar([=](int a){return *px += a*factor;});
}
as far as I can tell. But C++ also allows you to write something like
this:
int foo(vector<int> const& data) {
int accum = 0;
// The lambda object here doesn't outlive this scope
// so it's safe to capture by reference...
for_each(data.begin(),data.end(),[&](int x){accum+=x;});
return accum;
}
which doesn't involve any dynamic memory management w.r.t. the lambda
object and is potentially very fast (inlining of "accum+=x;"). If you
want to support this kind of syntax in C without templates you are
forced to implement this feature with an implicit level of
indirection. Unfortunately, this will remove the possible performance
advantage of lambda objects over function pointers in C++.
Cheers!
SG
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]