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

时间:2020-06-23 10:34:07

标签: c++ type-conversion c++20 user-defined-literals

考虑以下代码:

using char_type = /*implementation defined*/;

void foo(const char_type*);

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

字符串文字"Hello World!"是一个const char*,根据实现的不同,它可能无法转换为const char_type*。我希望我的代码在不同的实现之间可移植,所以我想我可以定义一个文字来将一个字符转换为另一个字符(这种转换类型可以保证工作):

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

,然后像foo("Hello World!"_s)这样使用它。但是,我能想到的唯一实现是使用new来分配空间和std::copy,但这将非常慢。我想在编译时进行转换,幸运的是,我可以使用c ++ 20和consteval关键字来确保对该函数的调用始终产生连续表达式(用户定义的文字仍然是普通函数,它们可以在运行时被调用)。知道如何实现吗?

1 个答案:

答案 0 :(得分:3)

此转换可以通过两步过程完成:首先,声明一个可以在编译时构造函数中将const char *转换为char_type数组的类;其次,通过在用户定义的文字中使用该类:

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

尝试on Godbolt。请注意,string_convert和用户定义的文字都不会出现在反汇编中。剩下的就是转换后的数组。