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

如何在C++中实现带格式化失败信息的断言?

标准实现方案

C++标准库原生的assert宏仅支持单个条件参数,无法直接传递格式化的失败消息,但可以通过以下标准合规的方式实现你需要的功能:

1. 封装带格式化消息的断言宏(C++20及以上)

利用C++20引入的std::format和std::source_location,可以封装一个支持自定义格式化消息的断言宏,同时保留原生assert在发布版(定义NDEBUG时)自动失效的特性:

#include <cstdio>
#include <format>
#include <source_location>
#include <cstdlib>

#ifdef NDEBUG
#define my_assert(expr, fmt, ...) ((void)0)
#else
#define my_assert(expr, fmt, ...) \
    do { \
        if (!(expr)) { \
            const auto msg = std::format(fmt, __VA_ARGS__); \
            const auto loc = std::source_location::current(); \
            std::fprintf(stderr, "Assertion failed: %s\nFile: %s\nLine: %d\nFunction: %s\nMessage: %s\n", \
                #expr, loc.file_name(), loc.line(), loc.function_name(), msg.c_str()); \
            std::abort(); \
        } \
    } while(false)
#endif

使用示例:

void func(int a, int b) {
    my_assert(a == b, "values differ: {} != {}", a, b);
}

2. 延迟生成消息的断言宏(性能优化)

如果希望仅在断言失败时才生成格式化消息(避免不必要的字符串处理开销),可以封装一个接受消息生成lambda的版本:

#include <cstdio>
#include <source_location>
#include <cstdlib>

#ifdef NDEBUG
#define my_assert_lazy(expr, msg_generator) ((void)0)
#else
#define my_assert_lazy(expr, msg_generator) \
    do { \
        if (!(expr)) { \
            const auto msg = msg_generator(); \
            const auto loc = std::source_location::current(); \
            std::fprintf(stderr, "Assertion failed: %s\nFile: %s\nLine: %d\nFunction: %s\nMessage: %s\n", \
                #expr, loc.file_name(), loc.line(), loc.function_name(), msg.c_str()); \
            std::abort(); \
        } \
    } while(false)
#endif

使用示例:

void func(int a, int b) {
    my_assert_lazy(a == b, [&](){ return std::format("values differ: {} != {}", a, b); });
}

注意事项

  • 上述实现完全基于C++标准特性,无编译器依赖;
  • 定义NDEBUG宏时,断言会被自动禁用,和原生assert行为一致;
  • 避免在断言消息中包含有副作用的代码(比如++a),因为发布版中这些代码不会执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 08:27:12