C++ 在编译时将const char*转换为const char_type*
考虑以下代码:C++ 在编译时将const char*转换为const char_type*,c++,type-conversion,c++20,user-defined-literals,C++,Type Conversion,C++20,User Defined Literals,考虑以下代码: using char_type = /*implementation defined*/; void foo(const char_type*); int main() { foo("Hello World!"); } 字符串literal“Hello World!”是一个const char*,根据实现的不同,它可能无法转换为const char\u type*。我希望我的代码可以在不同的实现之间移植,因此我想我可以定义一个文本来转换一个又一个
using char_type = /*implementation defined*/;
void foo(const char_type*);
int main()
{
foo("Hello World!");
}
字符串literal“Hello World!”
是一个const char*
,根据实现的不同,它可能无法转换为const char\u type*
。我希望我的代码可以在不同的实现之间移植,因此我想我可以定义一个文本来转换一个又一个字符(这种类型的转换保证有效):
然后像这样使用
foo(“你好,世界!”)
。然而,我能想到的唯一实现是使用new
来分配空间和std::copy
,但这将非常缓慢。我想在编译时进行转换,幸运的是,我可以使用c++20和consteval
关键字来确保对函数的调用始终生成contant表达式(用户定义的文本仍然是普通函数,可以在运行时调用它们)。知道如何实现这个吗?这个转换可以通过两个步骤来实现:首先,通过声明一个类,该类可以在编译时构造函数中将常量char*
转换为字符类型
数组;其次,通过在用户定义的文本中使用该类:
#include <algorithm>
template<std::size_t N>
struct string_convert {
char_type str[N] = {};
consteval string_convert(const char (&s)[N]) {
std::copy(s, s + N, str);
}
};
template<string_convert SC>
consteval auto operator ""_s()
{
return SC.str;
}
试试看。请注意,反汇编中既不显示
string\u convert
,也不显示用户定义的文字;剩下的就是转换后的数组。也许可以使用模板,例如std::basic_string
处理不同的字符类型?您也可以使用Microsoft的方法,使用宏自动为所有字符串文本添加合适的前缀,例如,定义T(s)L(s)或类似的,然后使用foo(T(“Hello world”)
std::basic_string
不能转换为std::basic_string
是T还是U不相等,此外,它不能在编译时使用。我从来没有听说过微软的这种方式,它是如何工作的?指针需要内存才能指向。consteval函数无法神奇地从任何地方产生内存。@n.'代词m。例如,实际上使用模板可以在编译时连接字符串。另一篇文章解释了如何做到这一点,即使它只适用于std::string_viewHmm的左值,看起来这需要非类型模板参数,但还没有在任何地方实现。很棒的解决方案!您还可以将构造函数更改为consteval string\u convert(const char&s)[N])
,这样您就可以省略演绎指南
#include <algorithm>
template<std::size_t N>
struct string_convert {
char_type str[N] = {};
consteval string_convert(const char (&s)[N]) {
std::copy(s, s + N, str);
}
};
template<string_convert SC>
consteval auto operator ""_s()
{
return SC.str;
}
void foo(const char_type *s);
foo("Hello, world!"_s);