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

如何使用标准库函数(非外部fmt库)创建含std::vector<std::string>参数的格式化字符串

使用C++标准库基于字符串向量创建格式化字符串

你的示例代码无法编译,核心原因是std::make_format_args是变参模板函数,要求直接传入单个格式化参数而非迭代器范围;同时C++标准库的std::format系列函数依赖编译时确定的参数数量,无法直接适配运行时动态大小的std::vector<std::string>。

下面分两种场景给出可行实现:


场景1:编译时已知参数数量

如果字符串向量的大小是编译时固定的,可以借助模板索引序列展开向量元素,适配std::vformat的要求:

#include <format>
#include <vector>
#include <string>
#include <utility>
#include <stdexcept>

namespace detail {
    template<std::size_t... Indices>
    std::string format_impl(const std::string& fmt, const std::vector<std::string>& args, std::index_sequence<Indices...>) {
        return std::vformat(fmt, std::make_format_args(args[Indices]...));
    }
}

// 模板参数N指定编译时确定的参数数量
template<std::size_t N>
std::string format_fixed(const std::string& fmt, const std::vector<std::string>& args) {
    if (args.size() != N) {
        throw std::invalid_argument("参数数量与预期不匹配");
    }
    return detail::format_impl(fmt, args, std::make_index_sequence<N>());
}

// 使用示例
int main() {
    std::vector<std::string> args = {"Alice", "Bob"};
    std::string result = format_fixed<2>("你好,{} 和 {}!", args);
    // result 为 "你好,Alice 和 Bob!"
    return 0;
}

场景2:运行时动态参数数量

如果参数数量是运行时不确定的,需要手动解析格式字符串,替换{0}、{1}这类占位符,同时处理转义的{{}}:

#include <string>
#include <vector>
#include <cstddef>
#include <stdexcept>
#include <algorithm>

std::string format(const std::string& fmt, const std::vector<std::string>& args) {
    std::string result;
    std::size_t pos = 0;
    const std::size_t fmt_len = fmt.size();

    while (pos < fmt_len) {
        // 查找下一个左大括号
        std::size_t open_brace = fmt.find('{', pos);
        if (open_brace == std::string::npos) {
            result += fmt.substr(pos);
            break;
        }

        // 追加左大括号之前的内容
        result += fmt.substr(pos, open_brace - pos);

        // 处理转义的{{
        if (open_brace + 1 < fmt_len && fmt[open_brace + 1] == '{') {
            result += '{';
            pos = open_brace + 2;
            continue;
        }

        // 查找对应的右大括号
        std::size_t close_brace = fmt.find('}', open_brace);
        if (close_brace == std::string::npos) {
            // 格式字符串不合法,追加剩余内容
            result += fmt.substr(open_brace);
            break;
        }

        // 解析占位符索引
        std::string index_str = fmt.substr(open_brace + 1, close_brace - open_brace - 1);
        try {
            std::size_t index = std::stoull(index_str);
            if (index < args.size()) {
                result += args[index];
            } else {
                // 索引超出范围,保留原占位符
                result += fmt.substr(open_brace, close_brace - open_brace + 1);
            }
        } catch (...) {
            // 索引不是合法数字,保留原占位符
            result += fmt.substr(open_brace, close_brace - open_brace + 1);
        }

        pos = close_brace + 1;
    }

    return result;
}

// 使用示例
int main() {
    std::vector<std::string> args = {"苹果", "香蕉", "橙子"};
    std::string result = format("我喜欢的水果:{0}、{1}、{2}", args);
    // result 为 "我喜欢的水果:苹果、香蕉、橙子"
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:25:16