为什么std::tr1::函数与Objective-C块一起工作?

Why does std::tr1::function work with Objective-C Blocks?

本文关键字:一起 工作 Objective-C std tr1 函数 为什么      更新时间:2023-10-16

当我发现下面的代码实际上可以工作时,我非常惊讶:

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

更新:我错了,这里是为什么它真正工作

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 的实现已经特别更新了以支持块)

虽然你可以把block当作Objective-C对象,并且Objective-C对block有很多支持,但是block并不局限于Objective-C。您也可以在C和c++中使用块。