首页 > 解决方案 > 在编译时将 const char* 转换为 const char_type*

问题描述

考虑以下代码:

using char_type = /*implementation defined*/;

void foo(const char_type*);

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

字符串文字"Hello World!"是 a 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关键字来确保对函数的调用总是产生一个常量表达式(用户定义的文字仍然是普通函数,它们可以在运行时调用) . 知道如何实现吗?

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

解决方案


这种转换可以通过两步过程进行:首先,通过在编译时构造函数中声明一个可以将 a 转换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);

在 Godbolt 上试试。请注意,string_convert反汇编中既不出现也不出现用户定义的文字;剩下的就是转换后的数组。


推荐阅读