为什么std :: tr1 :: function与Ob​​jective-C块一起使用?

时间:2011-04-09 19:31:46

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

当我发现以下代码确实有效时,我感到非常惊讶:

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块构造,但我不确定如何,因为(最后我检查过),它的实现并没有专门处理块。它是否以某种方式隐含地吮吸了底层函数指针?此外,这种行为是否未定义且可能会发生变化?

2 个答案:

答案 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