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

如何正确编写支持void返回类型的C++模板包装响应类

支持void返回类型的函数调用包装类实现

需求

  • 函数成功执行时,将结果存储到包装类的data字段中
  • 函数执行异常时,将异常转换为int类型的错误码

原实现问题

原代码无法支持返回类型为void的函数,因为当f()返回void时,res.data = f();这一行会触发编译错误——void类型的值不能被赋值给任何变量。

修改后的完整实现

#include <exception>
#include <iostream>
#include <type_traits>

struct ResponseBase
{
    int code = 0;
};

template<typename T>
struct Response : ResponseBase
{
    T data;
};

template<>
struct Response<void> : ResponseBase {
};

template<typename F>
auto try_catch_wrapper(F&& f)
{
    using ReturnType = decltype(f());
    Response<ReturnType> res;
    try
    {
        if constexpr (!std::is_void_v<ReturnType>)
        {
            res.data = f();
        }
        else
        {
            f(); // void返回类型直接调用,无需赋值
        }
    }
    catch (const std::exception&)
    {
        res.code = -1;
    }
    return res;
}

int main() {
    // 测试非void返回类型
    auto a = try_catch_wrapper([]() {
        return 1;
        });

    if (a.code == 0)
    {
        std::cout << "Invoke Success, Result: " << a.data << std::endl;
    }
    else
    {
        std::cout << "Error occured! Code: " << a.code << std::endl;
    }

    // 测试void返回类型
    auto b = try_catch_wrapper([]() {
        std::cout << "Void function executed!" << std::endl;
        });

    if (b.code == 0)
    {
        std::cout << "Void function invoke Success!" << std::endl;
    }
    else
    {
        std::cout << "Error occured! Code: " << b.code << std::endl;
    }
}

关键修改说明

  1. 使用using ReturnType = decltype(f());提取函数的返回类型,方便后续编译时判断
  2. 通过if constexpr (!std::is_void_v<ReturnType>)做编译时分支处理:
    • 当返回类型非void时,正常执行赋值操作存储结果
    • 当返回类型为void时,直接调用函数,跳过赋值步骤
  3. 若使用C++17之前的版本,可将std::is_void_v<ReturnType>替换为std::is_void<ReturnType>::value

修改后,包装类即可同时支持带返回值和无返回值的函数调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:22:43