c++ - 如果本地 std::function 超出其“生命”,是否有任何问题?
问题描述
你能帮忙检查一下下面的代码吗?如果本地 std::function 超出其“生命”,是否有任何问题?提前致谢。
class Test {
public:
void commit(std::function<void()> func)
{
// return immediately
dispatch_async(conqueue, ^{
// in order to call func when it is out of "life"
sleep(5);
func(); // is there any issue? the func should be invalid at this moment?
});
}
void test() {
std::string name = "test";
std::function<void()> func = [name, this] () {
printf("%lx %s\n", &name, name.c_str());
std::cout << "callback"<<std::endl;
};
// async
commit(func);
}
//...
};
解决方案
好的,我进行了一些测试并改变了对此的看法。代码是安全的,因为func
它是按值捕获的(即块继承了一个副本)。
我用以下测试程序向自己证明了这一点(你需要 MacOS 来运行它):
// clang block_test.mm -lc++
#include <iostream>
#include <unistd.h>
#include <dispatch/dispatch.h>
struct Captured
{
Captured () {}
Captured (const Captured &c) { std::cout << "Copy constructor\n"; }
void Foo () const { std::cout << "Foo\n"; }
};
int main ()
{
Captured c;
// return immediately
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
sleep(5);
c.Foo ();
});
sleep (10);
};
输出:
Copy constructor
Copy constructor
Foo
我不确定为什么复制构造函数被调用两次。问苹果。
更新:这里有一篇很好的关于使用块的文章。这就是那个有趣的“帽子”语法。
推荐阅读
- sql-server - 使用字段中的引号将 CSV 导入 SQL Server 的简单方法
- python - 使用相同的内容请求 google map api 并获得不同的结果
- php - 多重检查PHP
- c# - 在这种情况下如何在 C# 中使用 split
- erlang - 如何找回失去的
Ejabberd/MongooseIM 中与 XEP-0022 相关的事件 - apache-spark - PySpark 在创建包含现有列名的新列时读取多个文件
- javascript - 为组件上的隐藏属性设置动画的最佳方法
- r - 在基础 R 中按组返回最频繁的字符串
- r - 如何将向量的元素存储到矩阵的特定位置
- java - 如何在 SQL 查询中匹配字符串中的模式?