跳到主要内容
左猫娘右猫娘

【C++】如何将「字符串」作为「非类型模板实参」

· 阅读需 4 分钟
Heng_Xin
ここから先は一方通行だ!

冷门应用场景, 但是也算是比较方便吧~

Tip

环境: C++20

一、实现的效果

二、如何匹配非类型模板参数

附: C风格字符串, 是 const char (&)[N] 类型(C风格数组). 即: 数组不是指针...

using StrType = decltype("123"); // const char (&)[4]
auto& str = "123"; // const char (&)[4]

// 下面发生了隐式转换
using StrType = decltype(+"123"); // const char*
auto str = "123"; // const char*
cpp

2.1 <char... Cs>

template <char... Cs>
void strTp() {}

strTp<"123">(); // 报错, 显然不匹配
cpp

2.2 <auto Str>

C++17 auto占位非类型模版形参:

template <auto Str>
void strAutoTp() {}

strAutoTp<"123">(); // 报错, 它仅支持 整型常量/枚举常量/指针常量/成员指针/std::nullptr_t/ 浮点数(C++20)
// 未支持 const char* 或者 const char (&)[]
cpp

2.3 NTTP (C++20)

constexpr 类 实例作为模板参数

所以, 在 C++20 中, 我们可以自定义一个 constexpr 类, 并且其通过 C风格字符串 构造, 从而实现: 「字符串」作为「非类型模板实参」

三、代码实现

template <std::size_t N>
struct CStr {
char _str[N];

// constexpr 构造函数 + 默认析构
constexpr CStr(const char (&str)[N]) {
for (std::size_t i = 0; i < N; ++i)
_str[i] = str[i];
}

constexpr char operator[](std::size_t i) const noexcept {
return _str[i];
}

constexpr auto size() const noexcept {
return N - 1; // 去掉 '\0'
}
};

template <CStr Str> // CStr 可作为 NTTP 类型
void strCStrTp() {}

strCStrTp<"123">(); // 合法
cpp

其他的使用, 比如:

完整代码: https://godbolt.org/z/fqas758MK

请作者喝奶茶:
Alipay IconQR Code
Alipay IconQR Code
本文遵循 CC CC 4.0 BY-SA 版权协议, 转载请标明出处
Loading Comments...