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

如何将字符串字面量转换为char参数包实现编译期字符串拼接?

解决static_string与普通字符串字面量的编译期拼接问题

核心问题是普通字符串字面量作为const char*参数时,str[Is]无法成为常量表达式——因为指针退化为运行时类型,编译器无法确认其指向的是编译期可见的数组。解决思路是让编译器推导字符串字面量的编译期数组类型,而非指针,再通过std::index_sequence生成编译期索引来展开字符。

1. 修复make_static_string,支持编译期数组转换

利用模板推导数组大小,结合std::index_sequence生成编译期索引序列,确保str[Is]是常量表达式:

#include <utility>

template<size_t Size>
struct static_string {
    char data[Size]{};

    // 接收字符参数的constexpr构造函数
    constexpr static_string(char... chars) : data{chars...} {}

    // static_string之间的拼接逻辑
    template<size_t OtherSize>
    constexpr auto operator+(const static_string<OtherSize>& other) const {
        static_string<Size + OtherSize> result;
        // 编译期复制数据
        for (size_t i = 0; i < Size; ++i) {
            result.data[i] = data[i];
        }
        for (size_t i = 0; i < OtherSize; ++i) {
            result.data[Size + i] = other.data[i];
        }
        return result;
    }
};

// 辅助实现:通过索引序列展开字符
template<size_t N, size_t... Is>
constexpr auto make_static_string_impl(const char (&str)[N], std::index_sequence<Is...>) {
    // N包含末尾的'\0',生成Size=N-1的static_string
    return static_string<N-1>{str[Is]...};
}

// 对外接口:推导字符串数组大小,生成索引序列
template<size_t N>
constexpr auto make_static_string(const char (&str)[N]) {
    return make_static_string_impl(str, std::make_index_sequence<N-1>{});
}

// 自定义字面量(复用原有实现)
constexpr static_string<sizeof(str)-1> operator""_ss(const char* str, size_t size) {
    return make_static_string(str);
}

2. 添加与普通字符串字面量的拼接运算符

为static_string和const char[]重载operator+,直接复用已有static_string间的拼接逻辑:

// static_string + 普通字符串字面量
template<size_t LhsSize, size_t RhsSize>
constexpr auto operator+(const static_string<LhsSize>& lhs, const char (&rhs)[RhsSize]) {
    return lhs + make_static_string(rhs);
}

// 普通字符串字面量 + static_string
template<size_t LhsSize, size_t RhsSize>
constexpr auto operator+(const char (&lhs)[LhsSize], const static_string<RhsSize>& rhs) {
    return make_static_string(lhs) + rhs;
}

3. 测试示例

constexpr auto hello = "Hello"_ss;
constexpr auto hello_world = hello + "World";
// hello_world是static_string<10>,编译期内容为"HelloWorld"

constexpr auto hi_world = "Hi" + hello_world;
// hi_world是static_string<12>,编译期内容为"HiHelloWorld"

关键原理说明

  • 使用const char (&str)[N]作为参数时,编译器会推导字符串字面量的编译期数组大小N,此时str[Is]是常量表达式(数组是编译期可见的,索引Is由std::index_sequence生成,也是编译期常量)。
  • 若参数为const char*,编译器无法确认指针指向的是编译期数组,因此str[Is]无法在模板展开时作为常量表达式使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:44:51