【问题标题】:User-defined literals, underscores, and global names用户定义的文字、下划线和全局名称
【发布时间】:2012-10-04 06:36:05
【问题描述】:

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

long double operator "" _w(long double);

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

17.6.4.3.5 用户定义的文字后缀
不以下划线开头的文字后缀标识符保留用于将来的标准化。

但是,标准中的另一部分表明

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

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

  • 17.6.4.3.2(全局名称)的第二部分是否需要在命名空间(即不在全局命名空间)中定义用户定义的文字(如上面的_w)?如果是这样,我希望标准能够说明这一点。
  • 我认为 17.6.4.3.2(全局名称)的第一部分排除了用户定义的文字,例如 _W(后跟大写字母)和 __w_w__(两个连续的下划线)。正确吗?

编辑:

作为后续措施,标准的一部分说:

13.5.8 用户定义的文字
[...]
2 declarator-id 为 literal-operator-id 的声明应是命名空间范围函数或函数模板的声明(它可以是友元函数 (11.3))、显式实例化或函数模板的特化,或使用声明(7.3.3)。使用 literal-operator-id 声明的函数是文字运算符。使用 literal-operator-id 声明的函数模板是文字运算符模板。

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

后期编辑:

第一次提出问题时不存在,但现在还有this related question and answer,,读者可以在查看以下答案后额外检查。

【问题讨论】:

  • 哈,有趣!如果你问我,这看起来像是一个疏忽。
  • 文字后缀不是名称。根据该解释,17.6.4.3.2 不适用于 17.6.4.3.5。
  • Consider this。它仍然会被 pp 破坏,它可以应用于 _<capital>__,但是同名的全局变量(例如声明 _i 并制作后缀 _i)不冲突,所以没有第二条规则的全局范围部分会干扰您的后缀。
  • @chris:除了预处理器相当盲目地替换那里的令牌;这根本不表明它是一个名字。这类似于预处理器可以替换不是名称的关键字的方式。实际用作后缀时,它也不应该影响后缀。
  • From 3.3.6 Namespace scope [basic.scope.namespace]: "3 翻译单元的最外层声明区域也是一个命名空间,称为全局命名空间。在全局命名空间中声明的名称有全局命名空间范围(也称为全局范围)。[...]"

标签: c++ c++11


【解决方案1】:

名字里有什么? 3个基本概念[basic]告诉我们:

4 名称是标识符 (2.11)、operator-function-id (13.5)、literal-operator-id (13.5.8)、conversion-function-id (12.3.2) 或 template- 的使用id (14.2) 表示实体或标签 (6.6.4, 6.1)。

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

literal-operator-id
operator "" 标识符

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

operator""__w 这样的东西有问题的,但这不是新的:int i__0; 也是保留的。

【讨论】:

  • 那么区别是nameidentifier?全局命名空间中以下划线开头的名称是保留的,但不是标识符。
  • @KonradRudolph 这比这更聪明(让我做了三遍)。标识符必须表示某些东西,然后它是一个名称(具有适用的限制)。如果您只是声明operator"" _w(即在同一范围内没有int _w; 或其他),那么_woperator"" _w 中的标识符,但它本身并不表示任何东西(_w单独是无效的)所以它不是一个名字。
  • @LucDanton:文字_W(大写)不是也有问题,因为它成为实现定义的宏的潜在冲突吗?因为当你声明它时,引号和标识符之间必须有一个空格(即"" _W),所以_W 是预处理器替换的公平游戏。对吗?
  • @Cornstalks 我找不到任何错误的理由。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 2016-06-14
  • 2014-11-03
  • 1970-01-01
  • 2018-05-04
相关资源
最近更新 更多