在 C++20 中,我们可以使用
FixedString
将字符串文字作为模板参数传递:
#include <utility>
#include <iostream>
template <std::size_t N> struct FixedString {
char data[N];
template <std::size_t... I> constexpr FixedString(const char (&s)[N], std::index_sequence<I...>): data{s[I]...} {}
constexpr FixedString(const char (&s)[N]): FixedString(s, std::make_index_sequence<N>()) {}
};
template <FixedString s> void print() {
std::cout << '"' << s.data << '"';
}
template <char c> void print() {
std::cout << '\'' << c << '\'';
}
int main() {
print<"hello">(); // this works
print<'h'>(); // this works
}
但是,如果我尝试编写一个包装
print
函数的函数,如果我尝试使用字符串文字调用它,则会收到错误。
template <auto x> void print_wrapped() {
std::cout << '(';
print<x>();
std::cout << ')';
}
int main() {
print_wrapped<'h'>(); // this works
print_wrapped<"hello">(); // error
}
// <source>: In function 'int main()':
// <source>:25:28: error: no matching function for call to 'print_wrapped<"hello">()'
// 25 | print_wrapped<"hello">(); // error
// | ^
// <source>:17:24: note: candidate: 'template<auto x> void print_wrapped()'
// 17 | template <auto x> void print_wrapped() {
// | ^~~~~~~~~~~~~
// <source>:17:24: note: template argument deduction/substitution failed:
// <source>:25:28: error: '"hello"' is not a valid template argument for type 'const char*' // because string literals can never be used in this context
// 25 | print_wrapped<"hello">(); // error
// | ^
// Compiler returned: 1
如何编写单个版本的
print_wrapped
,将字符串文字或字符作为模板参数,并根据该参数分派到print
?
"hello"
是一个字符串文字。您可以使用用户定义的文字,如下所示:
template<FixedString A>
constexpr FixedString<A.size> operator""_S() requires(A.size >=1)
{
return FixedString<A.size>(A.data);
}
int main() {
print_wrapped<'h'>(); // this works
print_wrapped<"hello"_S>(); // works now
}