用户定义的文字、下划线和全局名称

时间:2022-07-24 05:01:14

In C++11, we get user-defined literals. The C++ standard has examples of these, such as:

在c++ 11中,我们得到用户定义的文字。c++标准有这些例子,例如:

long double operator "" _w(long double);

And it says the literal should start with an underscore:

它说文字应该以下划线开头:

17.6.4.3.5 User-defined literal suffixes
Literal suffix identifiers that do not start with an underscore are reserved for future standardization.

17.6.4.3.5用户定义的文字后缀——不以下划线开头的文字后缀——是为将来的标准化而预留的。

However, there's another section in the standard that says

然而,标准中还有另一个部分说。

17.6.4.3.2 Global names
Certain sets of names and function signatures are always reserved to the implementation:
— Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase letter (2.12) is reserved to the implementation for any use.
— Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.

17.6.4.3.2全局名称某些名称和函数签名始终保留给实现:-每个名称都包含一个双下划线_ _或以下划线开头,后跟一个大写字母(2.12),用于任何用途。-以下划线开头的每个名称都保留给实现,以便在全局名称空间中用作名称。

I'm looking to better understand exactly what 17.6.4.3.2 (Global names) says/means and how it relates to 17.6.4.3.5 (User-defined literal suffixes). Specifically:

我希望更好地理解17.6.4.3.2(全局名)的含义以及它与17.6.4.3.5(用户定义的文字后缀)的关系。具体地说:

  • Does the second part of 17.6.4.3.2 (Global names) require user-defined literals (like the above _w) to be defined in a namespace (that is, not in the global namespace)? If so, I wish the standard would've illustrated this.
  • 17.6.4.3.2(全局名称)的第二部分是否要求在名称空间中(即在全局名称空间中)定义用户定义的文字(如上面的_w) ?如果是这样的话,我希望标准已经说明了这一点。
  • I presume that the first part of 17.6.4.3.2 (Global names) rules out user-defined literals like _W (followed by upper case) and __w and _w__ (two consecutive underscores). Correct?
  • 我假定17.6.4.3.2(全局名称)的第一部分排除了用户定义的文字,如_W(后跟大小写)和__w和_w__(两个连续的下划线)。正确吗?

Edit:

编辑:

As a follow up, there's a part of the standard that says:

作为后续,标准中有一部分是这样的

13.5.8 User-defined literals
[...]
2 A declaration whose declarator-id is a literal-operator-id shall be a declaration of a namespace-scope function or function template (it could be a friend function (11.3)), an explicit instantiation or specialization of a function template, or a using-declaration (7.3.3). A function declared with a literal-operator-id is a literal operator. A function template declared with a literal-operator-id is a literal operator template.

13.5.8定义文字[…[2]声明其声明符-id为字元操作符-id的声明应是名称空间范围函数或函数模板的声明(可以是一个朋友函数(11.3))、函数模板的显式实例化或专门化或使用声明(7.3.3)。用文字操作符-id声明的函数是文字操作符。用文字操作符-id声明的函数模板是文字操作符模板。

Emphasis mine. When it says "namespace-scope" does that mean user-defined literals need to be declared in a user-defined namespace (i.e. not in the global namespace)?

我特别强调。当它说“名称空间-范围”时,这是否意味着用户定义的文字必须在用户定义的名称空间中声明(即不在全局名称空间中)?

Later edit:

后来编辑:

It did not exist when the question was first asked, but now there is also this related question and answer, which readers can additionally check after reviewing the answers below.

第一次被问到的时候并不存在,但是现在又有了这个相关的问题和答案,读者可以在看完下面的答案后再进行检查。

1 个解决方案

#1


7  

What's in a name? 3 Basic concepts [basic] tells us:

在一个叫什么名字?3基本概念[Basic]告诉我们:

4 A name is a use of an identifier (2.11), operator-function-id (13.5), literal-operator-id (13.5.8), conversion-function-id (12.3.2), or template-id (14.2) that denotes an entity or label (6.6.4, 6.1).

名称是标识符(2.11)、操作符-函数-id(13.5)、文本-操作符-id(13.5.8)、转换-函数-id(12.3.2)或表示实体或标签的模板-id(14.2)的使用。

which we cross-reference with 13.5.8 User-defined literals [over.literal]:

我们与13.5.8用户定义的文字[over.literal]交叉引用:

literal-operator-id:
operator "" identifier

literal-operator-id:运营商”“标识符

While the name of a literal operator involves an identifier, that identifier does not denote an entity. (Or it's a different identifier and different name that denotes another entity or label altogether.) As such the name of a literal operator never starts with an underscore.

虽然文字操作符的名称涉及标识符,但该标识符并不表示实体。(或者它是一个不同的标识符和不同的名称,表示另一个实体或标签。)因此,文字操作符的名称永远不会以下划线开头。

Something like operator""__w is problematic but this is not new: int i__0; is reserved as well.

像操作符“__w”这样的东西是有问题的,但这不是新的:int i__0;也保留。

#1


7  

What's in a name? 3 Basic concepts [basic] tells us:

在一个叫什么名字?3基本概念[Basic]告诉我们:

4 A name is a use of an identifier (2.11), operator-function-id (13.5), literal-operator-id (13.5.8), conversion-function-id (12.3.2), or template-id (14.2) that denotes an entity or label (6.6.4, 6.1).

名称是标识符(2.11)、操作符-函数-id(13.5)、文本-操作符-id(13.5.8)、转换-函数-id(12.3.2)或表示实体或标签的模板-id(14.2)的使用。

which we cross-reference with 13.5.8 User-defined literals [over.literal]:

我们与13.5.8用户定义的文字[over.literal]交叉引用:

literal-operator-id:
operator "" identifier

literal-operator-id:运营商”“标识符

While the name of a literal operator involves an identifier, that identifier does not denote an entity. (Or it's a different identifier and different name that denotes another entity or label altogether.) As such the name of a literal operator never starts with an underscore.

虽然文字操作符的名称涉及标识符,但该标识符并不表示实体。(或者它是一个不同的标识符和不同的名称,表示另一个实体或标签。)因此,文字操作符的名称永远不会以下划线开头。

Something like operator""__w is problematic but this is not new: int i__0; is reserved as well.

像操作符“__w”这样的东西是有问题的,但这不是新的:int i__0;也保留。