为什么std::tr1::函数与Objective-C块一起工作?
Why does std::tr1::function work with 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块构造,但我不确定如何,因为(上次我检查),它的实现并没有专门处理块。它是否以某种方式隐式地吸出底层函数指针?此外,这种行为是否未定义并且可能改变?
更新:我错了,这里是为什么它真正工作
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++中使用块。
相关文章:
- 如何使我的 sizeof sum 结构与空参数包一起工作
- SFINAE:它如何与派生类一起工作?
- std::remove() 按预期处理文字,但不能与取消引用的迭代器一起工作
- 尝试让条形码扫描仪与Arduino一起工作
- 从书本中学习C++无法使该程序与类一起工作
- 让类与运算符一起工作更简单的方法
- 如何使lambda与std::nullopt一起工作
- 当我使用长整型时,我的代码不起作用,它与 int 一起工作得很好
- 返回对象如何与分配运算符一起工作
- GLM :: perspective()和glm :: lookat()一起工作
- SFML OpenGL:如何同时与他们一起工作
- 使QTConcurrent ::映射与Lambdas一起工作
- 如何与C 字符串中的非ASCII字符一起工作
- 我如何适应擦除式习惯与矢量元组一起工作
- 需要帮助使 VOID 代码与总工资一起工作
- 我怎样才能让这个刽子手代码与 wxDev-C++ 一起工作
- Googletest 在 bazel test 中永远不会失败(在它应该失败的地方),但与 cmake & clion 一起工作
- 常量变量初始化仅与成员初始化列表一起工作
- feal_ptr与unique_ptr一起工作
- OpenGL Ping Pong可与一张通行证一起工作,而不是两个通行证