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

C++如何将字符数组包展开为字符数组及索引序列的模板参数

问题解答

你想要的编译期字符串拼接效果是可以实现的,但不能直接按照你写的伪代码语法实现,C++模板规则不支持你示例中那种分组交替的参数包定义方式,以下是可行的实现思路和代码示例。

你写的伪代码的语法问题

  • 模板参数列表不支持分组嵌套的可变参数包,template <char const *S0, size_t... I0, char const *S1, size_t... I1, ...>的写法不符合C++语法,可变参数包只能放在模板参数列表末尾,无法重复交替声明多组不同的参数包。
  • 函数形参strs属于运行期参数,不能直接作为模板非类型参数传递,C++要求非类型指针模板参数必须指向具有静态存储期的对象。

可行实现方案(C++20及以上)

我们可以通过辅助结构先把每个字符串和对应的索引序列打包,再展开拼接:

#include <utility>
#include <tuple>

// 辅助结构:包装单个字符串和对应的索引序列(去掉末尾的\0,所以索引序列长度是L-1)
template<const char* Str, typename Seq>
struct str_pack {};

// 将输入的所有字符串和对应索引序列打包
template<size_t... L>
constexpr auto pack_all_str(const char (&...strs)[L]) {
    return std::make_tuple(str_pack<strs, std::make_index_sequence<L-1>>{}...);
}

// 拼接逻辑实现
template<typename... Packs>
struct combine_impl;

// 递归终止:单个字符串包
template<const char* Str, size_t... Is>
struct combine_impl<str_pack<Str, std::index_sequence<Is...>>> {
    constexpr static char value[] = {Str[Is]..., '\0'};
};

// 递归拼接多个字符串包
template<const char* S0, size_t... I0, const char* S1, size_t... I1, typename... Rest>
struct combine_impl<str_pack<S0, std::index_sequence<I0...>>, str_pack<S1, std::index_sequence<I1...>>, Rest...> {
    constexpr static char value[] = {S0[I0]..., S1[I1]..., combine_impl<Rest...>::value..., '\0'};
};

// 对外调用接口
template<size_t... L>
constexpr const char* combine_str(const char (&...strs)[L]) {
    return combine_impl<decltype(pack_all_str(strs))...>::value;
}

// 使用示例
constexpr const char a[] = "hello";
constexpr const char b[] = "world";
constexpr auto res = combine_str(a, b); // 编译期得到"helloworld"

更简洁的constexpr函数实现(C++17及以上)

如果不需要严格用模板参数展开的形式实现,直接用constexpr函数拼接的写法更简洁,编译期也能得到相同的效果:

#include <array>
#include <string_view>

template<size_t... L>
constexpr auto combine_str(const char (&...strs)[L]) {
    constexpr size_t total_len = (L + ...) - sizeof...(L); // 减去每个字符串末尾的\0长度
    std::array<char, total_len + 1> arr{};
    size_t pos = 0;
    (([&] {
        for (size_t i = 0; i < L - 1; i++) arr[pos++] = strs[i];
    }()), ...);
    arr[total_len] = '\0';
    return arr;
}

// 使用示例
constexpr auto res = combine_str("hello", "world");
static_assert(res.data() == std::string_view("helloworld"));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:06:08