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

Jon*_*ing 10 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);
Run Code Online (Sandbox Code Playgroud)

似乎std::tr1::function能够从Objective-C块构建,但我不确定如何,因为(最后我检查过),它的实现并不专门处理块.它是否以某种方式隐含地吮吸了底层函数指针?此外,这种行为是否未定义且可能会发生变化?

pmd*_*mdj 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);
Run Code Online (Sandbox Code Playgroud)

它应该无法编译,因为块必须携带counter周围的捕获值.(当然,除非执行std::tr1::function 被专门更新以支持块)

  • 只要签名有效,`std(:: tr1):: function`完全不关心它应该调用什么.你应该从Objective-C块获得类似functor的东西,而`std(:: tr1):: function`可以完美地调用一个函数.我认为Objective-C块的工作类似于C++ 0x lambdas,而`std(:: tr1):: function`s可以对lambdas运行很好,因为它们基本上是仿函数.:) (4认同)