了解C ++ 20的用户定义字符串文字附加 [英] understanding user defined string literals addition for c++20

查看:107
本文介绍了了解C ++ 20的用户定义字符串文字附加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在用户定义的字符串文字中找到了以下内容:

I found in user defined string literal the following:



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




a)如果重载集包含带有非类型模板参数的字符串文字运算符模板,且该字符串的str如果是格式良好的模板参数,则将用户定义的文字表达视为函数调用 operator。 X< str>()

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

That sounds a bit mysterious to me. Can some one give an example how this can be used?

以下内容根本不起作用,我无法理解 MyType 即可。似乎不是char *或const char *:

The following did not work at all and I can't catch the point what the non type template parameter for MyType can be. It seems not a char* nor 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;
}


推荐答案

这是令人困惑的措辞,是从标准直接复制的直接复制

This is confusing wording, which was copied directly from the standard:


如果[重载集]包含带有非类型模板参数的文字运算符模板,且 str 是格式正确的template-argument

If [the overload set] contains a literal operator template with a non-type template parameter for which str is a well-formed template-argument

令人困惑的是,对于 str 是什么格式正确的模板参数专门适用于。从标准中直接阅读该段落表明针对。术语非类型模板参数是指非类型模板参数,因为那是直接在单词 for which之前的文本。但是,如果您查看该标准将如何调用该函数,则会看到以下内容:

The confusing bit is the question of what "for which str is a well-formed template argument" specifically applies to. A direct reading of the passage from the standard suggests that "for which" refers to the "non-type template parameter", since that is the text directly preceding the words "for which". However, if you look at how the standard says the function will be invoked, you see this:


operator "" X<str>()


str 正在传递给运算符,这意味着隐式转换将在 str 与 non-type之间进行模板参数。也就是说, str 是有效的模板参数, 重载函数的值,而不是重载函数的模板参数的值。因此,针对部分应引用带有非类型模板参数的文字运算符模板,而不是非类型模板参数。

str is being passed to the operator, which the implication being that an implicit conversion will take place between str and the "non-type template parameter". That is, str is a valid "template argument" of the overloaded function, not of the template parameter of the overloaded function. And thus, the "for which" part should refer to the "literal operator template with a non-type template parameter", not the "non-type template parameter".

已经说过了,要使代码正常工作,除了从 MyType 中删除​​模板参数之外,您还需要做更多的事情。

That having been said, to make your code work, you need to do more than to just remove the template argument from MyType.

您可能会已经注意到C ++中围绕非类型模板参数(NTTP)的某些奇怪之处。例如,NTTP一直可以作为事物的指针。但您永远无法做到这一点:

You might have noticed a certain oddity in C++ surrounding non-type template parameters (NTTP). For example, NTTPs have always been able to be pointers to things. But you could never do this:

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

该标准明确禁止指针NTTP初始化为字符串文字。而且C ++ 20 不会更改

The standard expressly forbids a pointer NTTP from being initialized with a string literal. And C++20 does not change this.

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

Therefore, you can't take a pointer. You have to take what the literal actually is: an array. But you can't make your code work by taking const char (&in)[] as a parameter either. A literal is not an unsized array (since an "unsized array" is not a real object type). That array parameter must be sized appropriately to the literal.

这意味着您必须根据大小模板参数推导

Which means that you must deduce the size from a size template parameter.

此外,其他规则完全禁止您存储指向以下内容的指针NTTP中的字符串文字(直接或间接)。因此,如果您想要一个类型来表示NTTP中的整个字符串文字,则该NTTP类型必须包含大小为该大小的数组。

Also, other rules flat-out forbid you from ever storing a pointer to a string literal in an NTTP (directly or indirectly). So, if you want a type that represents an entire string literal in an NTTP, that NTTP type must contain an array that is sized to that size.

因此最简单的函数字符串文字NTTP 您可以构建的将是

So the simplest, functional string literal 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< string_literal t>自动运算符 _y()来定义您的UDL。

And thanks to CTAD, you can just use template < string_literal t > auto operator ""_y() to define your UDL.

请注意,此 string_literal 类明确将NUL终止符包含在数组中。

Note that this string_literal class explicitly includes the NUL terminator as part of the array.

这篇关于了解C ++ 20的用户定义字符串文字附加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆