C ++ 0x lambda vs blocks

时间:2011-08-15 22:13:38

标签: c++ lambda c++11 objective-c-blocks

我今天正在探索C ++ 0x,我遇到了新的lambda功能。我的问题是blocks这些不同(就使用而言)是什么?为什么人们更喜欢一个而不是另一个?

感谢。

4 个答案:

答案 0 :(得分:5)

  

有一个简短的语法,使用C ++ 0x lambdas来获取每个变量   范围参考。 ([&])lambda的类型也未指定,   允许更优化的代码。

     

现在,当您查看Apple块时,它将需要__block说明符   添加到您想要修改的变量(这是事实   要求表明整个系统有缺陷)。变量被采用   通过引用,然后通过块,当块退出范围时(和   复制的上下文必然存在于堆上,似乎)。很奇怪   语义只会导致设计破碎,但可能会造成   喜欢GC的人很开心。不说这可能有相当的   当然,效率成本,因为这需要特殊的间接。

     

声称C ++ 0x lambdas语法会破坏与...的兼容性   C程序,但我不认为这是真的。可能还有其他的   但是,将它与C集成的问题主要是C不能的事实   真正处理未指定的类型和构建类型擦除。

     

Apple块实际上只是他们试图推广的ObjC功能   其他语言。对于C ++,为该语言设计的系统是   好多了。

编辑:

为了得到充分的肯定,我很久以前从http://www.rhinocerus.net/forum/language-c-moderated/558214-blocks-vs-c-lambdas.html获取了这些信息。那条链接已经死了;然而,原来的讨论似乎已归档here,感谢@stefan找到它。

答案 1 :(得分:5)

我认为这基本上归结为你的起点问题。如果您从Objective-C开始,并主要(或专门)编写C ++(Objective-C ++)作为Objective-C的附件,那么在所有代码中使用块可能是有意义的,只需保留尽可能多的通用性跨代码库。即使(例如)一个项目使用了一些用Objective-C编写的部分和其他用C ++编写的部分, 可以有意义地使用两个块尽可能保留整个代码库中的相似性。

但是,除非你在C ++之外使用它们,否则我认为没有理由比C ++ lambdas更喜欢块。在我猜中最常见的用法(算法中的谓词或动作)中,两者之间唯一明显的区别是,一个以^开头,另一个以[]开头。< / p>

旧版本的Objective C ++

在ARC之前,块和lambda的实现存在内部差异,这可能会影响一些更高级的用途。例如,块像C字符串一样模糊,因此您使用Block_copy复制一个,Block_release来释放副本,依此类推。另一方面,在C ++中,这一切都是自动化的,因此copy ctor会根据需要自动使用Block_copy和dtor Block_release。同时,它确实涉及更多“魔术”,因此(例如)复制块时,无论源的分配方式如何,副本总是动态分配。

如果由于某种原因,你仍然坚持使用较旧的(我很想说“古老”)编译器或维护较旧的代码(并且不希望整个代码库更新)记忆管理的差异可能值得考虑。

答案 2 :(得分:1)

迈克·阿什提供detailed comparison。块和lambdas的语法,数据类型,捕获变量的方式,复制时的行为方式以及性能都有所不同。

它们与C / C ++ / Objective-C的关系:

  

我将把Apple的块扩展称为“Objective-C blocks”   虽然这不完全正确。它们实际上是一个补充   C(甚至可以在C ++中使用),还有一些额外的行为   它们在Objective-C中更有用。然而,它们是深深交织在一起的   在Objective-C的实现中,“C blocks”是模糊的,所以   我认为“Objective-C blocks”是引用它们的最佳方式   这里。

     

C ++ 0x lambdas只是C ++的一部分,无法从C中使用。   据推测,如果编译器支持,它们可以在Objective-C ++中使用   的C ++ 0x。

差异的非常高级别的总结:

  

Objective-C块的编写和使用稍微简单一些,   特别是在将它们用于异步或后台的情况下   必须复制块并保持活动的任务   创建它的范围的生命周期。 C ++ 0x lambdas最终   提供更多的灵活性和潜在的速度,但代价是   相当复杂的增加。

答案 3 :(得分:0)

截至最近的clang版本(3.2,3.3rc和3.4svn),它们可以在Objective-C(++)代码中互换。在C ++中,你必须使用lambda,但如果你有

,则使用Objective-C(++)
  • libobjc中的C ++支持。
    Apple的libobjc.B.dylib肯定有它。如果您正在使用GNUstep,则需要使用cmake编译libobjc2(并且只使用libobjc2)并链接libsupc ++(或您使用的任何C ++ ABI库)或将项目链接到libobjcxx以及
  • 块运行时应该存在。
    它是OS X上的libSystem.dylib的一部分,它与libc相关联,因此它不是一个问题。您可以使用LLVM编译器-rt或使用libobjc2。我个人建议你使用libobjc2,因为它提供了一个与GNUstep的其余部分兼容的Blocks运行时,它也被称为。
  • 基础套件。
    这是由于clang如何处理交换C ++ lambda和Objective-C块的ABI。与NSAutoreleasePool合作,这是Foundation的一部分。

然后你可以安全地交换零件。