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

移动promise时出现“Attempt to use a deleted function”错误求助

解决Mac上Promise/Future代码的“Attempt to use a deleted function”错误

Hey there, let's break down why your promise/future code works online but throws that annoying deleted function error on your Mac, and how to fix it!

核心原因分析

First off, std::promise and std::future are non-copyable types—their copy constructors and copy assignment operators are explicitly deleted by the C++ standard. The error you're seeing happens when your code accidentally tries to copy these objects instead of using move semantics.

The discrepancy between online compilers and your Mac usually comes down to two things:

  • Your Mac's default compiler (Clang via Xcode) might be older, with stricter or less complete support for C++11/14 move semantics compared to newer online compiler versions.
  • You might have subtle copy operations in your code that online compilers (with more lenient or updated checks) don't flag, but Mac's Clang catches immediately.

具体排查&修复步骤

1. 检查所有Promise/Future的传递方式

Look for any place you're passing std::promise or std::future by value—this triggers a copy, which is not allowed.

错误示例(触发拷贝):

// 按值传递promise,会尝试调用已删除的拷贝构造函数
void process_data(std::promise<std::string> prom) {
    prom.set_value("Done!");
}

int main() {
    std::promise<std::string> my_prom;
    // 这里直接传my_prom,是拷贝操作
    std::thread t(process_data, my_prom); 
    t.join();
    return 0;
}

正确写法(用移动语义):

// 接收右值引用,允许移动
void process_data(std::promise<std::string>&& prom) {
    prom.set_value("Done!");
}

int main() {
    std::promise<std::string> my_prom;
    auto fut = my_prom.get_future(); // 先获取future,移动后promise不可用
    // 用std::move触发移动语义
    std::thread t(process_data, std::move(my_prom)); 
    t.join();
    std::cout << fut.get() << std::endl;
    return 0;
}

或者用引用(结合std::ref):
If you need to keep using the original promise object after passing it to a thread, pass it by reference with std::ref:

void process_data(std::promise<std::string>& prom) {
    prom.set_value("Done!");
}

int main() {
    std::promise<std::string> my_prom;
    auto fut = my_prom.get_future();
    // 用std::ref传递引用,避免拷贝
    std::thread t(process_data, std::ref(my_prom)); 
    t.join();
    std::cout << fut.get() << std::endl;
    return 0;
}

2. 检查容器中的Promise/Future存储

If you're storing promise or future objects in containers like std::vector, make sure you're using emplace_back with std::move instead of push_back (which tries to copy):

错误:

std::vector<std::promise<int>> promises;
std::promise<int> p;
promises.push_back(p); // 拷贝操作,报错

正确:

std::vector<std::promise<int>> promises;
std::promise<int> p;
promises.emplace_back(std::move(p)); // 移动插入,合法

3. 确保编译器启用了正确的C++标准

Mac's Clang might default to an older C++ standard (like C98) if you don't specify otherwise. Compile your code with at least C11 support:

g++ -std=c++17 your_file.cpp -o your_program -pthread
# 或者用clang++
clang++ -std=c++17 your_file.cpp -o your_program -pthread

Note: -pthread is required for threading support on most systems.

4. 更新你的Mac编译器

If you're using an older version of Xcode, it might have outdated Clang with buggy move semantics support. Update Xcode to the latest version via the App Store, or install a newer Clang/GCC via Homebrew:

brew install llvm
# 然后用clang++ from llvm来编译
/usr/local/opt/llvm/bin/clang++ -std=c++17 your_file.cpp -o your_program -pthread

额外提醒

Online compilers (like Godbolt, Compiler Explorer, or CodeSandbox) typically use the latest compiler versions with full C++ standard support, which is why your code works there but not on your Mac. The key fix is eliminating any accidental copy operations on std::promise/std::future and ensuring your compiler is set up to handle modern C++ features.

内容的提问来源于stack exchange,提问作者MaestroMaus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:43:13