Hol*_*Cat 5 c++ templates c++11
当我发现可以将用户定义的文字模板化时,我感到很惊讶:
template <char ...C> std::string operator ""_s()
{
char arr[]{C...};
return arr;
}
// ...
std::cout << 123_s;
Run Code Online (Sandbox Code Playgroud)
但以上声明不适用于字符串文字:
"123"_s
Run Code Online (Sandbox Code Playgroud)
给我以下错误:
prog.cpp:在函数'int main()'中:
prog.cpp:12:15:错误:没有匹配的函数可调用'operator“” _ s()'
std :: cout <<“ 123” _s;prog.cpp:4:34:注意:候选:模板std :: string运算
符“” _s()模板std :: string运算符“” _s()prog.cpp:4:34:注意:模板参数推导/替换失败:
有没有办法将模板化的用户定义文字与字符串文字一起使用?
在 C++20 之前,这在标准 C++ 中是不可能的。请参阅@TC 的答案,了解适用于 GCC 和 Clang 的非标准解决方案。
从 C++20 开始,您可以将字符串文字作为模板参数传递。您需要一个像这样的辅助类:
#include <algorithm>
#include <cstddef>
#include <string_view>
namespace impl
{
// Does nothing, but causes an error if called from a `consteval` function.
inline void ExpectedNullTerminatedArray() {}
}
// A string that can be used as a template parameter.
template <std::size_t N>
struct ConstString
{
char str[N]{};
static constexpr std::size_t size = N - 1;
[[nodiscard]] std::string_view view() const
{
return {str, str + size};
}
consteval ConstString() {}
consteval ConstString(const char (&new_str)[N])
{
if (new_str[N-1] != '\0')
impl::ExpectedNullTerminatedArray();
std::copy_n(new_str, size, str);
}
};
Run Code Online (Sandbox Code Playgroud)
它允许您执行以下操作:
#include <iostream>
template <ConstString S>
void Print()
{
std::cout << S.view() << '\n';
}
int main()
{
Print<"foo">();
}
Run Code Online (Sandbox Code Playgroud)
这可能足以满足您的用例,并且您可能不需要模板 UDL 本身。
但如果你确实需要它们,这是可能的:
#include <iostream>
template <ConstString S>
void operator""_print()
{
std::cout << S.view();
}
int main()
{
"foo"_print;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
594 次 |
| 最近记录: |