是否可以将 C++0x lambda 转换为 clang 块?
我想知道是否可以将 C++0x lambda 转换为 clang 块。到目前为止,我所看到的一切都涉及到他们之间差异的讨论。我研究这个的主要原因是为 libdispatch
制作一个最终的包装器,虽然我非常了解 dispatch_*_f
函数,但有关其使用的任何信息都有与他们的区块相比,这是相当缺乏的。
到目前为止,我已经能够找到有关 将 C++ lambda 转换为函数指针,但这更多的是相反的领域。
如果有人知道与此相关的任何信息,并且可以提供链接,或者至少为我指出正确的方向,我将非常感激。 (即使是“目前不可能”的答案就足够了)
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我建议使用 libdispatch 函数的
*_f
版本。所有的块版本都是根据底层的函数版本来实现的,编写一个生成调用 lambda 对象的函数的 C++ 模板比编写一个生成调用 lambda 的块的模板要容易得多一个 lambda 对象。然而,目前 Clang 缺乏对 C++ lambda 的支持可能会给整个事情带来阻碍。
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.
隐式启用此转换的补丁刚刚添加到 clang trunk 中。
A patch enabling this conversion implicitly was just added to clang trunk.
一般来说,当 lambda 用于“向下”闭包时,可以通过 conversion:
to:
将 c++ lambda 转换为 clang 块,但仍然存在一些细微的差异。 Clang 的块仅通过 const 捕获 C++ 类。我不知道这是否也包括 C++ POD 类型。
最后,如果需要“向上”闭合,那么两者就会出现巨大分歧。 Clang 的块需要捕获的变量用
__block
注释,编译器将在堆上分配它。而在 C++ 中,lambda 捕获的方式需要根据对象的生命周期来决定(即通过值进行复制或通过引用)。同样在 C++ 中,复制闭包是由 C++ 中的复制构造函数机制自动处理的。然而,对于clang的块,需要调用
Block_copy
和Block_release
来处理块的复制。可以用 C++ 编写一个简单的包装器来处理这个问题。例如: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:我认为实际的转变是不可能的。与相反的情况不同,摆脱原来的 clang 块会产生一些无法恢复的副作用。虽然 C++0x lambda 可以通过引用捕获变量,但当您实际打算使用 lambda 时,没有执行任何特殊操作来确保原始变量仍然存在。另一方面,块可以与使用 __block 存储限定符声明的变量进行交互,在这种情况下,这些变量将保留在内存中(即使这意味着从堆栈复制到堆),只要该块存在(包括由
Block_copy
制作的副本):因此,除非您打算保留原始块(从而包装而不是转换它),否则它的一些原始功能将丢失,因为
__block
变量将消失。然而,我不是这方面的专家,很想听听其他意见:)
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 :)
嗯,Clang 还不支持 lambda,Apple GCC 也不支持。 FSF GCC 最近足以支持 lambda 不支持块 AFAIK。所以它们之间的转换问题还不适用。
一旦 Clang 支持这两者,ObjC++ 模式中可能就有一种方法可以在它们之间进行转换。
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.