当我发现以下代码确实有效时,我感到非常惊讶:
std::vector<int> list /*= ...*/;
std::tr1::function<void(int)> func = ^(int i) {
return i + 1;
};
std::for_each(list.begin(), list.end(), func);
似乎std::tr1::function
能够从Objective-C块构造,但我不确定如何,因为(最后我检查过),它的实现并没有专门处理块。它是否以某种方式隐含地吮吸了底层函数指针?此外,这种行为是否未定义且可能会发生变化?
答案 0 :(得分:6)
更新:我错了,这就是为什么它真的有效
std::tr1::function
的模板参数只是定义了生成的函数对象的签名,而不是它实际包装的类型。因此,包装对象只需要提供具有匹配签名的operator()
。块引用(如函数指针)隐式具有operator()
(显然,您可以调用它们)。
旧的,错误的答案(所以评论有意义)
我强烈怀疑它是否有效,因为该块不会捕获周围范围内的任何变量。在这种情况下,没有要维护的状态,因此块引用可以表示为裸函数指针。如果我们将代码更改为
std::vector<int> list /*= ...*/;
int counter = 0;
std::tr1::function<void(int)> func = ^(int i) {
counter++;
return i + counter;
};
std::for_each(list.begin(), list.end(), func);
它应该无法编译,因为块必须带有捕获的counter
值。 (当然,std::tr1::function
的实施已经专门更新以支持块)
答案 1 :(得分:0)
虽然您可以将块视为Objective-C对象,而Objective-C对块有很多支持,但块不仅限于Objective-C。您还可以在C和C ++中使用块。有关详细信息,请参阅this article。