使用std::async出现“No viable overloaded '='”错误,求C++11/C++20差异及解法
问题分析与解决方案
错误根源
你遇到的"No viable overloaded '='"错误,核心原因有两个:
- 返回类型不匹配:函数
f的返回值是void,但你声明的std::future<int>类型与之冲突。std::async调用无返回值函数时,返回的是std::future<void>,而非std::future<int>,类型不匹配导致赋值操作无法找到合适的重载。 - 线程ID输出格式错误:
std::this_thread::get_id()返回的是std::thread::id类型,不能直接用%d格式化输出,这会导致未定义行为,建议转成long类型后用%ld输出,或改用std::cout。
C11与C20的相关语法差异
针对std::future和std::async的核心规则,两个标准没有本质差异:
std::future从C11开始就支持移动语义(不可拷贝,仅能移动),C20未修改这一特性。临时对象(比如std::async的返回值)的赋值会自动触发移动操作,所以这不是你当前错误的原因。std::async的返回类型规则在C11到C20中保持一致:返回std::future<R>,其中R是被调用函数的返回类型。因此你遇到的类型不匹配问题,在两个标准下都会触发。- C++20仅对
std::async的启动策略细节做了微调,和当前错误无关。
修复方案
方案一:修正std::future类型(推荐)
将std::future<int>改为std::future<void>,匹配f的void返回类型:
#include <future> #include <thread> #include <cstdio> void f(int n){ for(int i=0; i<n; i++){ // 修正线程ID的输出格式 printf("Thread[%ld]: %d\n", static_cast<long>(std::this_thread::get_id()), i); } } int main(int argc, const char * argv[]) { int thCNT = 5; std::future<void> mTH[thCNT]; // 修改为std::future<void> for(int i=0; i<thCNT; i++){ mTH[i] = std::async(f, i+5); } for(int i=0; i<thCNT; i++){ mTH[i].get(); // std::future<void>::get()无需返回值 } return 0; }
方案二:修改函数f的返回值
如果需要std::future<int>,可以给f添加int类型的返回值:
#include <future> #include <thread> #include <cstdio> int f(int n){ for(int i=0; i<n; i++){ printf("Thread[%ld]: %d\n", static_cast<long>(std::this_thread::get_id()), i); } return n; // 添加int类型返回值 } int main(int argc, const char * argv[]) { int thCNT = 5; std::future<int> mTH[thCNT]; for(int i=0; i<thCNT; i++){ mTH[i] = std::async(f, i+5); } for(int i=0; i<thCNT; i++){ int result = mTH[i].get(); // 可以获取返回值 // 可选:输出返回值 // printf("Thread %d returned: %d\n", i, result); } return 0; }
内容的提问来源于stack exchange,提问作者JoJolllee
相关产品推荐
相关产品推荐

