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

C++23:如何实现带编译时格式符与参数数校验的sprintf类函数

C++23无宏实现格式化字符串编译时参数校验

需求

我正在学习C++23,计划编写一个类似sprintf()的函数,核心要求如下:

  • 当传入字符串字面量作为格式串时,在编译时检查%占位符的数量与传入参数数量是否匹配
  • 校验通过后生成并返回格式化字符串,暂不考虑具体格式化逻辑

现有实现的问题

最初的尝试代码无法实现编译时校验,原因是Sprintf()中调用的std::to_string()并非常量表达式(使用GCC trunk,开启--std=c++2b编译选项)。如果移除std::to_string()并将两个函数标记为consteval,虽然能实现编译时校验,但会严重限制函数功能——比如无法使用std::to_string()、无法创建/操作并返回std::string。

我知道可以通过可变参数宏实现:先调用consteval的count_percents()完成参数数量校验,再调用非consteval的辅助函数执行格式化,但认为C++23应该有更优雅的无宏方案。

最初的问题代码:

#include <iostream>

template <int N>
constexpr size_t count_percents(const char (&s)[N]) {
    size_t count = 0;
    for (size_t i = 0; i < N; i++) 
        if (s[i] == '%') ++count;
    return count;
}

template <int N, typename... Args>
constexpr std::string Sprintf(const char (&format)[N], Args&&... args) {
    if (count_percents(format) != sizeof...(args)) 
        throw std::invalid_argument("wrong number of placeholders in format string");

    return (std::to_string(args) + ...);
}

int main() {
    std::cout << Sprintf("%%", 1, 2);  // 输出"12",符合预期

    // 期望编译失败,但实际会通过编译并在运行时抛出异常
    std::cout << Sprintf("%", 1, 2); 
}

曾找到相关参考方案,但仅适用于校验逻辑仅依赖格式串的场景,无法满足我基于非consteval函数参数数量触发编译错误的需求。

自解方案

我自己实现了一个可完成编译时参数数量校验的方案,代码如下:

#include <cstddef>
#include <iostream>

consteval size_t count_percents(const char* s) {
    size_t i = 0;
    while (*s) if (*s++ == '%') ++i;
    return i;
}

template <size_t N>
struct format_string {
  const char* str;

  consteval format_string(const char* s) : str(s) {
    if (N != count_percents(str))
        // 若此代码路径被实例化,consteval函数中的throw会触发编译错误
        throw std::invalid_argument("wrong number of placeholders");
  }
};

template <typename... T>
void my_print(format_string<sizeof...(T)> format, T&&... args) {
    // 执行到此处说明占位符数量校验通过
}

int main() {
    my_print("foo%%%", 1, 2, 3);   // 正常编译
    // my_print("foo%", 1, 2, 3);  // 触发编译错误!
}

不过存在更优的方案,该方案不仅能校验参数数量,还支持检查实际参数类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 05:53:14