用户自定义字面量、下划线和全局名称

11

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)在声明时位于namespace中(即不在全局命名空间中)?如果是这样,我希望标准能够说明这一点。
  • 我认为17.6.4.3.2的第一部分(全局名称)是否排除了类似_W(后面跟大写字母)和__w_w__(两个连续下划线)等用户定义的文字常数。正确吗?

编辑:

随着后续的发展,标准中还有部分内容:

  

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

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

稍后编辑:

当问题被提出时,它不存在,但现在还有这个相关的问题和答案,读者可以在查看下面的答案之后再进行额外检查。


1
哈哈,有趣!如果你问我,那看起来像是一个疏忽。 - Konrad Rudolph
字面后缀不是名称。根据这种解释,17.6.4.3.2不适用于17.6.4.3.5。 - nneonneo
1
请考虑以下内容:这里。它仍然会被pp搞乱,pp可以应用于_<capital>__,但是同名的全局变量(例如声明_i并添加后缀_i)不会冲突,因此第二条规则中的全局作用域部分不会干扰您的后缀。 - chris
1
@chris:除了预处理器相当盲目地替换标记外,它并不表示它是一个名称。这类似于预处理器可以替换不是名称的关键字的方式。当实际用作后缀时,它也不应影响后缀。 - nneonneo
从3.3.6 命名空间作用域 [basic.scope.namespace]:“3 翻译单元的最外层声明区域也是一个命名空间,称为全局命名空间。在全局命名空间中声明的名称具有全局命名空间作用域(也称为全局作用域)。[...]” - Luc Danton
1个回答

8
一个名字有什么用?《C++ Primer》中的[基本]章节告诉我们:
名称是标识符(2.11)、运算函数ID(13.5)、字面值运算符ID(13.5.8)、转换函数ID(12.3.2)或模板ID(14.2)的使用,它表示实体或标签(6.6.4、6.1)。
我们将其与13.5.8用户定义的字面量 [over.literal]进行交叉引用: literal-operator-id: operator "" identifier 尽管文字操作符的名称涉及标识符,但该标识符并不表示实体。 (或者它是一个不同的标识符和不同的名称,表示完全不同的实体或标签。)因此,文字操作符的名称从不以下划线开头。
像operator""__w这样的东西确实存在问题,但这并不是新问题:int i__0;也是保留的。

那么区别在于名称标识符吗?以下划线开头的全局命名空间中的名称是保留的,但标识符不是。 - Konrad Rudolph
2.11 标识符 [lex.name] 是定义“标识符”的地方,严格来说它是一种语法结构。 - Luc Danton
2
@LucDanton:字面意义上的“_W”(大写)也存在问题,因为它可能成为实现定义宏的潜在冲突?因为当你声明时,引号和标识符之间必须有一个空格(即 "" _W),所以 _W 可以被预处理器替换。正确吗? - Cornstalks
1
@Cornstalks 我找不到任何错误的理由。 - Luc Danton
1
此外,https://dev59.com/zFzUa4cB1Zd3GeqP57vj。 - Johannes Schaub - litb
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接