【问题标题】:understanding user defined string literals addition for c++20了解 c++20 的用户定义字符串文字添加
【发布时间】:2020-11-01 08:03:34
【问题描述】:

我在user defined string literal 发现了以下内容:

  1. 对于用户定义的字符串文字,让 str 为不带 ud 后缀的文字:

a) 如果重载集包含带有非类型模板参数的字符串文字运算符模板,其中 str 是格式正确的模板参数,则用户定义的文字表达式被视为函数调用operator "" X<str>()

这对我来说听起来有点神秘。有人可以举例说明如何使用它吗?

以下内容根本不起作用,我无法理解MyType 的非类型模板参数可以是什么。它似乎不是 char* 也不是 const char*:

template < ??? >
struct MyType 
{
    const char* c;
    constexpr MyType( const char* in ): c{in}{}
};

template < MyType t > auto operator ""_y() { return t; }

int main()
{
    "Check it"_y;
}

【问题讨论】:

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


    【解决方案1】:

    这是一个令人困惑的措辞,它是copied directly from the standard

    如果 [重载集] 包含带有非类型模板参数的文字运算符模板,而 str 是一个格式良好的模板参数

    令人困惑的是“str 是一个格式良好的模板参数”具体适用于什么的问题。直接阅读标准中的段落表明“for which”指的是“非类型模板参数”,因为这是直接在“for which”之前的文本。但是,如果您查看标准如何说明该函数将被调用,您会看到:

    operator "" X<str>()
    

    str 被传递给操作员,这意味着在str 和“非类型模板参数”之间将发生隐式转换。也就是说,str重载函数 的有效“模板参数”,而不是重载函数的模板参数。因此,“for which”部分应该指的是“带有非类型模板参数的文字运算符模板”,而不是“非类型模板参数”。

    话虽如此,要使您的代码正常工作,您需要做的不仅仅是从 MyType 中删除模板参数。

    您可能已经注意到 C++ 中围绕非类型模板参数 (NTTP) 的一些奇怪之处。例如,NTTP 总是能够成为事物的指针。但你永远不能这样做:

    template<const char *literal> void foo() {}
    foo<"literal">();
    

    该标准明确禁止使用字符串字面量初始化指针 NTTP。而 C++20 并没有改变这一点

    因此,您不能使用指针。您必须采用文字实际上是什么:一个数组。但是您也不能通过将const char (&amp;in)[] 作为参数来使您的代码正常工作。文字不是未调整大小的数组(因为“未调整大小的数组”不是真正的对象类型)。该数组参数必须根据字面量调整大小

    这意味着您必须从尺寸模板参数中推断尺寸。

    另外,other rules 明确禁止您在 NTTP 中存储指向字符串文字的指针(直接或间接)。因此,如果您想要一个表示 NTTP 中整个字符串文字的类型,该 NTTP 类型必须包含一个大小为该大小的数组。

    所以最简单的函数式字符串字面量 NTTP you could build would be:

    template<size_t N>
    struct string_literal
    {
        std::array<char, N> arr_;
    
        constexpr string_literal(const char(&in)[N]) : arr_{}   
        {
            std::copy(in, in + N, arr_.begin());
        }
    };
    

    感谢 CTAD,您可以使用 template &lt; string_literal t &gt; auto operator ""_y() 来定义您的 UDL。

    请注意,此 string_literal 类明确包含 NUL 终止符作为数组的一部分。

    【讨论】:

    • C++20 实际上确实允许像这样引用未知边界的数组;在没有其他方法可以了解大小的情况下,它们只是不是很有用。 (此外,我不确定考虑 UDL 函数或其 NTTP 是否会有所不同,因为隐式转换会以任何一种方式发生。)
    猜你喜欢
    • 2019-06-07
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 1970-01-01
    相关资源
    最近更新 更多