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);