如何在编译时重复拼接字符串?C++模板实现疑问
编译时重复拼接字符串的C++模板实现方案
你现有的编译时字符串结构体CnstString可以存储固定字符序列,现在希望通过递归模板实现同一字符串的编译时重复拼接,并在最终结果末尾追加'\0'。你尝试编写的RepeatStr模板存在参数传递错误,无法实现字符的累积拼接。
你的原始代码
基础字符串结构体
template<char... Chars> struct CnstString { template<char... Aped> using push_back = CnstString<Chars..., Aped...>; constexpr static char value[] = {Chars...}; };
基础使用示例
#include <iostream> using str = CnstString<'H', 'e', 'l', 'l', 'o', '\0'>; int main() { std::cout << str::value << std::endl; // 输出 "Hello" return 0; }
错误的递归拼接模板
template<int N, typename Str> struct RepeatStr { using ret = RepeatStr<N-1, Str>; // 错误:未实现字符串拼接,仅传递原字符串 }; template<typename Str> struct RepeatStr<-1, Str> { using ret = Str:: template push_back<'\0'>; };
错误分析
- 递归逻辑错误:每次递归仅传递原字符串
Str,没有将已经拼接的结果作为参数传递,无法实现累积拼接。 - 终止条件不合理:用
-1作为终止点不够直观,且未处理初始重复次数为正整数的常规场景。 - 原字符串提前加
'\0'会导致拼接后的字符串中间出现终止符,输出时会被截断。
正确实现方案
首先需要一个字符串拼接辅助模板合并两个CnstString类型;然后修改递归模板,每次递归将原字符串拼接到当前结果中,最终在终止时追加'\0'。
#include <iostream> template<char... Chars> struct CnstString { template<char... Aped> using push_back = CnstString<Chars..., Aped...>; constexpr static char value[] = {Chars...}; }; // 辅助模板:拼接两个CnstString template<typename S1, typename S2> struct ConcatStr; template<char... C1, char... C2> struct ConcatStr<CnstString<C1...>, CnstString<C2...>> { using type = CnstString<C1..., C2...>; }; // 递归核心模板:N为剩余重复次数,OriginalStr是原字符串,CurrentStr是当前已拼接结果 template<int N, typename OriginalStr, typename CurrentStr> struct RepeatStrImpl { using type = typename RepeatStrImpl<N-1, OriginalStr, typename ConcatStr<CurrentStr, OriginalStr>::type>::type; }; // 终止条件:剩余次数为0时,给当前结果追加'\0' template<typename OriginalStr, typename CurrentStr> struct RepeatStrImpl<0, OriginalStr, CurrentStr> { using type = typename CurrentStr::template push_back<'\0'>; }; // 对外接口模板:默认初始拼接结果为空字符串 template<int N, typename OriginalStr> struct RepeatString { static_assert(N >= 0, "Repeat count must be non-negative"); using type = typename RepeatStrImpl<N, OriginalStr, CnstString<>>::type; };
使用示例
int main() { // 原字符串不要提前加'\0',避免拼接后中间出现终止符 using hello = CnstString<'H', 'e', 'l', 'l', 'o'>; // 重复拼接3次hello using hello3 = RepeatString<3, hello>::type; std::cout << hello3::value << std::endl; // 输出 "HelloHelloHello" return 0; }
关键说明
ConcatStr模板负责将两个CnstString的字符序列合并,生成新的CnstString类型。RepeatStrImpl通过递归逐步累积拼接结果,每次递归将原字符串追加到当前结果后,直到剩余次数为0。RepeatString作为对外接口,简化用户调用,默认初始结果为空字符串,并添加断言确保重复次数非负。- 原字符串无需提前添加
'\0',所有拼接完成后统一在末尾追加,保证输出完整。
内容的提问来源于stack exchange,提问作者Konvt
相关产品推荐
相关产品推荐

