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

C++20 std::format如何实现fmt::dynamic_format_arg_store等效功能

C++20 std::format 动态参数构建方案说明

核心限制

目前C20、C23的标准库没有公开和fmt::dynamic_format_arg_store等效的接口,不依赖编译器私有实现的前提下,无法完全复刻fmt库的动态参数构建逻辑,核心原因有两个:

  • std::basic_format_args只是参数集合的类型擦除视图,本身不持有参数生命周期,也没有公开的动态添加参数的接口
  • 标准仅提供了std::make_format_args用来构造参数视图,它只能接收编译期数量确定的参数,没有提供运行时构造单个std::basic_format_arg的公开方法

可行替代方案

如果一定要用标准库实现动态参数格式化,可根据场景选择以下实现:

方案1:预格式化参数后拼接

这是最通用、完全符合标准要求的实现,适合所有场景,仅性能略低于原生的动态参数构建:

#include <format>
#include <vector>
#include <string>
#include <iostream>

int main() 
{
  // 动态存储预格式化的参数
  std::vector<std::string> dyn_args;
  dyn_args.push_back(std::format("{}", 42));
  dyn_args.push_back(std::format("{}", std::string{"abc1"}));
  dyn_args.push_back(std::format("{}", 1.5f));

  // 若参数数量运行时可确定,直接按索引传入std::format即可
  std::cout << std::format("{} this is my {}. This is a number: {}.", 
    dyn_args[0], dyn_args[1], dyn_args[2]) << "\n";

  // 若参数数量完全动态,可自行遍历替换格式字符串占位符
  const std::string fmt_str = "{} this is my {}. This is a number: {}.";
  std::string result;
  size_t arg_idx = 0;
  size_t pos = 0;
  while (pos < fmt_str.size()) {
    if (fmt_str[pos] == '{' && pos + 1 < fmt_str.size() && fmt_str[pos+1] == '}') {
      if (arg_idx < dyn_args.size()) {
        result += dyn_args[arg_idx++];
      }
      pos += 2;
    } else {
      result += fmt_str[pos++];
    }
  }
  std::cout << result << "\n";
}

方案2:限定参数类型的轻量实现

如果你的动态参数只有有限几种固定类型,可以自行实现类型擦除包装类,为其特化std::formatter后即可直接存入容器,编译期确定参数数量时可以直接传给std::format。

后续规划

目前已有相关提案计划向C++标准中加入动态格式化参数的公开接口,待后续标准版本落地后就可以用标准接口实现和fmt库一致的功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:36:03