C++14中如何将字符串字面量转为字符序列传入模板类char...参数包?
让
String<"abcd">合法的实现方案 针对你定义的接收字符参数包的模板结构体String,要让String<"abcd">这种写法合法,核心是把字符串字面量的每个字符拆分为char...参数包传递给模板。下面分不同C++标准版本给出实现方式:
C++20 简洁实现
C++20支持字符串字面量作为非类型模板参数,我们可以通过辅助模板结合索引序列来展开字符:
#include <cstddef> // 你定义的原模板结构体 template<char ...pack> struct String{}; // 辅助模板:接收字符串字面量,推导长度并展开字符 template<size_t N, const char (&Str)[N]> struct StringLiteralHelper { // 利用索引序列逐个提取字符 template<size_t... Idx> static constexpr auto build(std::index_sequence<Idx...>) { return String<Str[Idx]...>{}; } // 生成最终的String类型 using Type = decltype(build(std::make_index_sequence<N-1>{})); }; // 别名模板简化使用 template<const char (&Str)[N]> using StringLiteral = typename StringLiteralHelper<N, Str>::Type; // 使用示例 int main() { StringLiteral<"abcd"> str; // 等价于String<'a','b','c','d'> }
也可以用更简洁的模板lambda写法:
#include <cstddef> template<char ...pack> struct String{}; // 直接生成String实例的函数模板 template<size_t N, const char (&s)[N]> constexpr auto make_string() { return []<size_t... I>(std::index_sequence<I...>) { return String<s[I]...>{}; }(std::make_index_sequence<N-1>{}); } // 使用示例 constexpr auto str = make_string<"abcd">();
C++17 兼容实现
C++17不允许直接将字符串字面量作为非类型模板参数,但可以通过constexpr全局字符串配合索引序列实现:
#include <cstddef> template<char ...pack> struct String{}; // 辅助函数:通过索引序列展开字符串字符 template<const char* Str, size_t... Idx> constexpr String<Str[Idx]...> unpack_string(std::index_sequence<Idx...>) { return {}; } // 包装函数:自动计算字符串长度并调用展开逻辑 template<const char* Str> constexpr auto make_string() { // constexpr方式计算字符串长度 constexpr size_t len = []{ size_t l = 0; while(Str[l] != '\0') ++l; return l; }(); return unpack_string<Str>(std::make_index_sequence<len>{}); } // 定义constexpr全局字符串(必须是全局/静态存储期) constexpr const char abcd[] = "abcd"; // 使用示例 int main() { constexpr auto str = make_string<abcd>(); // 等价于String<'a','b','c','d'> }
另一种方式是用自定义字面量,更贴近直接写"abcd"的用法:
#include <cstddef> template<char ...pack> struct String{}; // 自定义字面量运算符,将字符串转为String实例 constexpr auto operator""_str(const char* str, size_t len) { return []<size_t... I>(const char* s, std::index_sequence<I...>) { return String<s[I]...>{}; }(str, std::make_index_sequence<len>{}); } // 使用示例 constexpr auto str = "abcd"_str; // 等价于String<'a','b','c','d'>
内容的提问来源于stack exchange,提问作者lei hu
相关产品推荐
相关产品推荐

