如何在C++中实现异步延迟60秒后执行函数?
解决std::async调用类成员函数的编译错误与返回值疑惑
一、先搞定C3867编译错误
你碰到的C3867错误,核心问题是类的非静态成员函数不能直接当作普通函数传给std::async——这类函数天生需要绑定一个类实例(也就是this指针)才能调用。你的两种写法都踩了坑:
- 第一种
this->model_log.refresh_data是直接写成员函数名,没有转换成正确的成员函数指针; - 第二种
this->model_log.refresh_data()是直接执行了函数,把返回的bool值传给了std::async,完全不符合函数参数的要求。
正确的调用方式有三种,按需选择:
1. 传递成员函数指针+类实例
void MVC::refresh_data() { // 注意:&Log::refresh_data 是成员函数指针,第二个参数传入类实例 std::future<bool> retCode = std::async(&Log::refresh_data, this->model_log); // 如果不想拷贝实例,想传递引用,用std::ref包裹 // std::future<bool> retCode = std::async(&Log::refresh_data, std::ref(this->model_log)); }
2. 使用Lambda表达式(最直观推荐)
用lambda把成员函数调用包裹起来,自动捕获上下文,写法清晰不容易出错:
void MVC::refresh_data() { std::future<bool> retCode = std::async([this]() { return this->model_log.refresh_data(); }); }
3. 使用std::bind绑定成员函数与实例
这种方式稍显繁琐,但也是可行的:
void MVC::refresh_data() { auto bound_func = std::bind(&Log::refresh_data, &this->model_log); std::future<bool> retCode = std::async(bound_func); }
二、澄清:std::async完全支持void返回值
你觉得“std::async不支持void返回类型”是个误解哦。如果你的refresh_data改成void返回,只需要把std::future<bool>换成std::future<void>就可以正常使用,比如:
// 假设refresh_data改成void返回 void Log::refresh_data() { std::this_thread::sleep_for(std::chrono::minutes(1)); std::vector<std::string> file_info = this->file.read_pending_if(); for(auto line : file_info) { this->append(line); } } // 对应的调用代码 void MVC::refresh_data() { std::future<void> ret = std::async(&Log::refresh_data, this->model_log); // 或者用lambda写法 std::future<void> ret = std::async([this]() { this->model_log.refresh_data(); }); }
额外小提示
如果你不需要等待异步任务的结果,也可以不存储std::future——但要注意:std::async返回的future对象被销毁时,会阻塞当前线程直到异步任务完成。如果想确保真正异步执行不阻塞,建议显式指定异步策略:
// 显式要求异步执行,避免默认的延迟执行策略 std::future<bool> retCode = std::async(std::launch::async, &Log::refresh_data, this->model_log);
内容的提问来源于stack exchange,提问作者LearnMore
相关产品推荐
相关产品推荐

