gpt4 book ai didi

c++ - 另一个字符串文字,UDL 迷宫

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:42:18 28 4
gpt4 key购买 nike

注意:这是 MSVC,C++17 问题。

免责声明:我知道有人尝试过,是的,我试图找到相关的 SO 答案。

我可以编码 UDL , 以实现将数字文字转换为 std::array,在编译时:

    // std::array{ '1','2','3' }
constexpr auto a_1 = 123_std_char_array;

// std::array{ '0','x','1','2' }
constexpr auto a_2 = 0x12_std_char_array;

// std::array{ '4'.'2','.','1','3' }
constexpr auto a_3 = 42.13_std_char_array;

这是我制作的 UDL:

    template< char ... Chs >
inline constexpr decltype(auto) operator"" _std_char_array( )
{
// append '\0'
return std::array { Chs..., char(0) } ;
}

惊人的,时髦的,现代的,废话,废话,废话......但是。

问题

我如何编写 UDL 以允许这样做:

    // std::array {'S','t','r','i','n','g'}
constexpr auto std_char_array_buff_ =
"String"_std_char_array ;

请使用 MSVC、C++17。

忏悔

我知道要“捕获”字符串文字的 UDL 必须具有以下足迹:

  inline auto operator"" _X( const char*, size_t);

我知道如何在编译时将字符串文字转换为 std::array。但没有 UDL。 Please see here , 寻找灵感。

是的,我知道 C++20 将添加 UDL 模板,而 GCC、clang 现在还有其他东西。虽然我看不出这对我有什么帮助。

最后,我知道我可以做到:

     constexpr auto string_view_ = "String"sv ;

最佳答案

不幸的是,这在 C++17 中似乎是不可能的。根据 [lex.ext]/5user-defined-string-literal 只能匹配 operator""X(str, len) .那么,len是一个函数参数,函数参数不能转换为模板参数。就像你不能这样做一样:

template <int N>
struct S {};

constexpr auto f(int n)
{
return S<n>{}; // no, n is not guaranteed to be known at compile time
}

"foo"sv 起作用是因为大小不是 std::basic_string_view 的模板参数,而是恰好受益于 constexpr。你不能用 std::array 来做,因为大小是 std::array 的模板参数。

make_array 之所以有效,是因为它不是文字运算符,因此它可以将大小作为模板 参数而不是函数 参数。然后,它可以将模板参数传递给 std::array。文字运算符无法做到这一点。


在 C++20 中,我认为我们可以使用这样的包装器类型:

template <std::size_t N>
struct helper {
std::array<char, N> string;

template <std::size_t... Is>
constexpr helper(const char (&str)[N + 1], std::index_sequence<Is...>)
:string{str[Is]...}
{
}
constexpr helper(const char (&str)[N + 1])
:helper{str, std::make_index_sequence<N>{}}
{
}
};

template <std::size_t N>
helper(const char (&str)[N]) -> helper<N - 1>;

然后使用字符串字面量运算符模板:

template <helper str> // placeholder type for deduction
constexpr auto operator""_S()
{
return str.string;
}

static_assert("foo"_S == std::array{'f', 'o', 'o'});

C++20 还没有最终确定,所以我不能肯定。

关于c++ - 另一个字符串文字,UDL 迷宫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57551935/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com