You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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无法自动填充该默认参数**:

  1. std::atomic_ref<T>::wait的标准签名为:
    void wait(T old, std::memory_order order = std::memory_order::seq_cst) const noexcept;
    
    它需要两个参数,第二个order带有默认值。
  2. 直接调用atom.wait(1)时,编译器会自动将第二个参数补全为默认的std::memory_order::seq_cst,因此可以正常编译。
  3. 但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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 23:50:28