简体   繁体   English

在编译时将 const char* 转换为 const char_type*

[英]Convert const char* to const char_type* at compile time

Consider the following code:考虑以下代码:

using char_type = /*implementation defined*/;

void foo(const char_type*);

int main()
{
    foo("Hello World!");
}

The string literal "Hello World!"字符串文字"Hello World!" is a const char* that, depending on the implementation, may not be convertible to const char_type* .是一个const char* ,根据实现,可能无法转换为const char_type* I want my code to be portable between different implementations so I thought I could define a literal to convert one char after another (this type of conversion is guaranteed to work):我希望我的代码可以在不同的实现之间移植,所以我想我可以定义一个文字来一个接一个地转换一个字符(这种类型的转换保证可以工作):

consteval const char_type* operator"" _s(const char*, size_t);

and then use it like this foo("Hello World!"_s) .然后像这样使用它foo("Hello World!"_s) However, the only implementation I can think of uses new to allocate space and std::copy but that would be extremely slow.但是,我能想到的唯一实现使用new来分配空间和std::copy但这会非常慢。 I want to make the conversion at compile time and luckily I can use c++20 and the consteval keyword to ensure that the call to the function always produces a contant expression (user defined literals are still normal functions, they can be called at runtime).我想在编译时进行转换,幸运的是我可以使用 c++20 和consteval关键字来确保对 function 的调用总是产生一个常量表达式(用户定义的文字仍然是普通函数,它们可以在运行时调用)。 Any idea how to implement this?知道如何实现吗?

This conversion is possible through a two-step process: first, by declaring a class that can convert a const char * to a char_type array within a compile-time constructor;这种转换可以通过两个步骤进行:首先,通过声明一个 class 可以在编译时构造函数中将const char *转换为char_type数组; second, by using that class within a user-defined literal:其次,通过在用户定义的文字中使用该 class :

#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;
}

This interface allows for the following use:该接口允许以下用途:

void foo(const char_type *s);

foo("Hello, world!"_s);

Try it on Godbolt .在 Godbolt 上试试 Note that neither string_convert nor the user-defined literal appear in the disassembly;注意string_convert和用户定义的文字都没有出现在反汇编中; all that remains is the converted array.剩下的就是转换后的数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM