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

C++线程池实现中std::promise处理void返回值类型报错求解

C++线程池void返回值适配方案

问题原因

std::promise<void>的set_value成员函数为无参设计,你当前代码统一将f(args...)作为参数传入set_value,当函数返回值为void时,f(args...)没有返回值,无法作为参数传递,因此触发编译错误。无参数函数异常通常是参数没有做完美转发导致的值类别匹配错误。

解决方案

方案1:C++17及以上版本(推荐)

使用if constexpr做编译期分支区分,同时用std::invoke兼容普通函数、成员函数、lambda等所有可调用对象,配合完美转发处理参数:

#include <future>
#include <functional> // std::invoke

template <typename F, typename...Args>
auto addWork(F&& f, Args&&... args) -> std::future<decltype(f(args...))>
{
    using ReturnType = decltype(f(args...));
    std::promise<ReturnType> result;

    if constexpr (std::is_void_v<ReturnType>) {
        std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
        result.set_value(); // void类型调用无参set_value
    } else {
        result.set_value(std::invoke(std::forward<F>(f), std::forward<Args>(args)...));
    }

    return result.get_future();
    // 后续将任务加入线程池队列的逻辑写在这里
}

方案2:C++11/14版本兼容

通过模板函数重载区分void和非void返回场景:

#include <future>
#include <utility>

// 非void返回值处理逻辑
template<typename ReturnType, typename F, typename... Args>
void fill_promise(std::promise<ReturnType>& prom, F&& func, Args&&... args)
{
    prom.set_value(std::forward<F>(func)(std::forward<Args>(args)...));
}

// void返回值特化逻辑
template<typename F, typename... Args>
void fill_promise(std::promise<void>& prom, F&& func, Args&&... args)
{
    std::forward<F>(func)(std::forward<Args>(args)...);
    prom.set_value();
}

// addWork实现
template <typename F, typename...Args>
auto addWork(F&& f, Args&&... args) -> std::future<decltype(f(args...))>
{
    using ReturnType = decltype(f(args...));
    std::promise<ReturnType> result;
    fill_promise(result, std::forward<F>(f), std::forward<Args>(args)...);
    return result.get_future();
    // 后续将任务加入线程池队列的逻辑写在这里
}

两种方案都可以同时解决void返回值适配、无参数函数调用异常的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:24:04