为何std::async调用std::atomic_ref::wait会出现编译失败?
std::async调用std::atomic_ref::wait编译失败的原因分析
测试代码
#include <future> #include <iostream> #include <atomic> #include <thread> struct Dummy { Dummy() : value(0) {} void add(int i) { value +=i;} int value; }; void func(){} int main() { // Dummy::add Dummy foo; auto f = std::async(&Dummy::add, &foo, 77); f.get(); std::cout << foo.value << "\n"; // std::thread::join std::thread t(func); auto f2 = std::async(&std::thread::join, &t); // std::atomic_ref::wait size_t a = 0; std::atomic_ref<size_t> atom(a); atom.wait(1); // 正常运行 auto f1 = std::async(&std::atomic_ref<size_t>::wait, &atom, 1); // 编译错误 }
编译错误信息
<source>:29:23: error: no matching function for call to 'async(void (std::__atomic_ref<long unsigned int, true, false>::*)(long unsigned int, std::memory_order) const noexcept, std::atomic_ref<long unsigned int>*, int)'
错误成因
编译失败的核心原因是**std::atomic_ref::wait的成员函数包含带默认值的参数,但std::async无法自动填充该默认参数**:
std::atomic_ref<T>::wait的标准签名为:
它需要两个参数,第二个void wait(T old, std::memory_order order = std::memory_order::seq_cst) const noexcept;order带有默认值。- 直接调用
atom.wait(1)时,编译器会自动将第二个参数补全为默认的std::memory_order::seq_cst,因此可以正常编译。 - 但
std::async在绑定成员函数时,模板参数推导不会识别成员函数的默认参数。你仅传递了1作为成员函数的第一个参数,std::async会尝试匹配需要两个参数的成员函数签名,由于缺少第二个order参数,导致签名不匹配,触发编译错误。
对比你之前成功的案例:
Dummy::add是明确的单参数成员函数,参数数量完全匹配,无默认参数问题。std::thread::join是无参数成员函数,同样不存在默认参数导致的推导问题。
解决方法
有两种常见的修复方式:
- 显式传递默认内存序参数:
auto f1 = std::async(&std::atomic_ref<size_t>::wait, &atom, 1, std::memory_order::seq_cst); - 用lambda封装调用逻辑:
auto f1 = std::async([&atom](){ atom.wait(1); });
内容的提问来源于stack exchange,提问作者ExpertNoob1
相关产品推荐
相关产品推荐

