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

如何在C++中遍历可变参数模板参数实现字符串替换?

可变参数模板实现字符串替换的正确方式

你当前的代码存在两个核心问题:

  • 参数包rest是编译期展开的序列,无法通过下标rest[i]直接访问;
  • 递归调用Replace(rest...)没有利用返回结果,且每次都重新获取原始模板字符串,会覆盖之前的替换操作。

实现思路

通过递归展开参数包的方式,逐个处理每个参数,每次替换模板中的一个%s占位符:

  1. 基础重载:当没有额外参数时,返回最终处理后的字符串;
  2. 模板重载:每次接收一个参数,替换当前字符串中的第一个%s,再递归处理剩余参数,传递已替换后的字符串。

修正后的完整代码

#include <string>
#include <iostream>
#include <utility> // 用于std::forward

const std::string& FindOriginal(const std::string& Key)
{
    static const std::string toon_template = "This is example %s in my program for Mr. %s.";
    static const std::string empty_str = "";
    
    if(Key == "Toon")
    {
        return toon_template;
    }
    
    return empty_str;
}

// 基础重载1:初始调用无额外参数时返回模板字符串
std::string Replace(const std::string& OriginalKey) {
    return FindOriginal(OriginalKey);
}

// 基础重载2:递归到无剩余参数时返回当前字符串
std::string Replace(std::string current_str) {
    return current_str;
}

// 模板重载:处理单个参数 + 剩余参数包
template<typename First, typename... Strings>
std::string Replace(const std::string& OriginalKey, First&& arg, Strings&&... rest)
{
    // 仅第一次调用时获取原始模板,后续递归使用已替换的字符串
    std::string current_str = (sizeof...(Strings) == sizeof...(rest)) 
        ? FindOriginal(OriginalKey) 
        : OriginalKey;
    
    const std::string placeholder = "%s";
    size_t pos = current_str.find(placeholder);
    
    if(pos != std::string::npos)
    {
        // 替换第一个占位符为当前参数,完美转发减少拷贝
        current_str.replace(pos, placeholder.length(), std::forward<First>(arg));
    }
    
    // 递归处理剩余参数,传递已替换后的字符串
    return Replace(std::move(current_str), std::forward<Strings>(rest)...);
}

int main()
{
    // 输出:This is example 5 in my program for Mr. Jimmy.
    std::cout << Replace("Toon", "5", "Jimmy") << std::endl;    
}

关键细节说明

  • 完美转发:使用std::forward传递参数,避免字符串等类型的不必要拷贝,提升性能;
  • 递归终止条件:两个基础重载分别处理初始无参数和递归到无剩余参数的情况;
  • 参数包展开:每次递归只处理一个参数,逐步替换占位符,直到参数包为空;
  • 模板字符串复用:仅第一次调用FindOriginal获取模板,后续递归直接使用已修改的字符串,避免重复获取。

额外优化(可选)

如果需要处理参数数量与占位符不匹配的情况,可以在替换时添加判断:

  • 若没有找到占位符但仍有剩余参数:可以抛出异常或打印警告;
  • 若占位符未被全部替换:可以选择保留或清空剩余占位符。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 13:50:28