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

如何优化C++20中使用格式化库抛出异常的写法?

更简洁的C++20格式化异常抛出方案

你可以通过封装模板函数、自定义异常类或者宏来简化带格式化信息的异常抛出,不用每次手动写std::format,以下是几种实用方案:

1. 封装模板函数(推荐)

写一个通用的模板函数,把格式化和抛异常的逻辑打包,同时利用C++20的std::format_string做编译期类型检查,避免格式字符串和参数不匹配的问题:

#include <stdexcept>
#include <format>
#include <utility> // 用于std::forward

template<typename... Args>
[[noreturn]] void throw_runtime_error(std::format_string<Args...> fmt, Args&&... args) {
    throw std::runtime_error(
        std::format(fmt, std::forward<Args>(args)...)
    );
}

使用时直接调用函数,写法简洁很多:

throw_runtime_error("Critical error! Code {}: {}", errno, strerror(errno));

如果需要抛出其他类型的异常(比如std::logic_error),可以扩展模板支持指定异常类型:

template<typename ExceptionType, typename... Args>
[[noreturn]] void throw_formatted_exception(std::format_string<Args...> fmt, Args&&... args) {
    static_assert(std::is_base_of_v<std::exception, ExceptionType>, 
                  "ExceptionType must inherit from std::exception");
    throw ExceptionType(std::format(fmt, std::forward<Args>(args)...));
}

// 使用示例:抛出logic_error
throw_formatted_exception<std::logic_error>("Invalid argument: {}", arg_value);

2. 自定义格式化异常类

如果需要区分不同的异常类型或扩展异常功能,可以写一个继承自标准异常的类,在构造函数里处理格式化:

#include <stdexcept>
#include <format>
#include <string>

class formatted_runtime_error : public std::runtime_error {
public:
    template<typename... Args>
    explicit formatted_runtime_error(std::format_string<Args...> fmt, Args&&... args)
        : std::runtime_error(std::format(fmt, std::forward<Args>(args)...)) {}
};

使用时直接抛自定义异常:

throw formatted_runtime_error("Critical error! Code {}: {}", errno, strerror(errno));

这种方式后续还能给异常类添加额外成员(比如错误码)或方法,扩展性更强。

3. 宏定义(极致简洁但需谨慎)

如果追求最短的写法,可以用宏封装,但要注意宏的局限性(比如参数中的逗号需要用括号包裹、调试时栈信息不够清晰):

#include <stdexcept>
#include <format>

#define THROW_RUNTIME_ERROR(fmt, ...) \
    throw std::runtime_error(std::format(fmt, __VA_ARGS__))

使用时:

THROW_RUNTIME_ERROR("Critical error! Code {}: {}", errno, strerror(errno));

若参数包含逗号(比如std::pair<int, int>),需用括号包裹参数避免解析错误:

THROW_RUNTIME_ERROR("Pair value: {}", (std::make_pair(1, 2)));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 16:15:05