给出以下测试用例
int main(int argc, char const* argv[]) {
{
constexpr wchar_t const* v = gstring<"hello world", wchar_t>();
std::wcout << v << std::endl;
std::wcout << std::wcslen(v) << std::endl;
}
{
constexpr char const* v = gstring<L"world hello", char>();
std::wcout << v << std::endl;
std::wcout << std::strlen(v) << std::endl;
}
return 0;
}
输出应该是
hello world
11
world hello
11
#include <cstring>
#include <iostream>
#include <string>
template <typename Char, unsigned N>
struct Capture {
Char string_[N + 1]{};
template <typename TChar>
consteval Capture(TChar const* string) {
for (unsigned index = 0; index < N+1; ++index) {
string_[index] = string[index];
}
}
template <typename TChar>
consteval auto As() const{
return Capture<TChar, N>(string_);
}
};
template <typename TChar, unsigned N>
Capture(TChar const (&)[N]) -> Capture<TChar, N - 1>;
template <Capture string, typename Char, auto cast = string.template As<Char>()>
consteval auto gstring() {
return cast.string_;
}
它需要两个阶段的过程。第一步是使用隐式转换为类型
const char *
来捕获 Capture
。第二步是调用 As
上的 Capture
方法将缓冲区转换为新类型。所有这些都是通过模板参数完成的,以确保文字对象是全局的。gstring 方法可以将内部最终缓冲区返回为 consteval
,因为
cast.string_
是模板参数,因此是编译时间常量。查看 GodBolt 上的解决方案
https://godbolt.org/z/GaTnh69cM