2012-12-10 20 views
3

关于下划线名称的问题部分回答了here,,但答案不完整,或者我没有完全理解。下划线,名称和文字运算符

Sect。在C++ 11标准的2.14.8.7声明此字面操作者作为一个例子:

long double operator "" _w(long double); 

除了声明操作中,标准及其实施例做进一步的两件事情是,如果单独看,每个有意义:

  • 它开始名称_w带下划线;和
  • 它将运算符放在全局名称空间中。

我的问题有两个部分:

  1. 根据the answer linked above,名称_w不是标识符,或标识_w是不是一个名,或...好,我是米困惑。
  2. 如果_w没问题,那么大写的_W也可以 - 60.0_W,意思是60.0瓦特?还是预处理器可能会错误地处理大写的版本?

毫无疑问,和你一样,我不习惯用下划线开始全局名称,这是习惯标准教派的习惯。 17.6.4.3.2.1显然似乎不赞成。因此,如果您可以对下划线,名称和文字操作符进行一些更多的说明,则可以欣赏灯光。

+1

'_W'会引起麻烦,作为一个'#定义_W/* *什么/'之前字面经营者的定义会导致'_W'到被替换。这不是'_W'中的'_W'被保留,但是实现可能像上面那样有一个宏'_W'。现在,人们可能会怀疑标准是否真的允许在字面操作符标识符上进行宏替换,并且我会说是,因为'_W'是一个单独的预处理器标记。 – Xeo

+0

@Xeo:谢谢。你碰巧知道标准中的哪个地方解释说'_W'会引起麻烦吗?如果是这样,我想阅读该部分。 – thb

+2

对于预处理阶段/标记,大多是子条款2.2和2.5。 '_W'是一个*标识符*,因此它是一个*预处理标记*,如果它命名一个宏,它将在阶段4中展开。 – Xeo

回答

10

好的,我从Clang团队的Richard Smith那里查了一下,你的文字操作符中的_W部分确实不是一个保留的标识符和/或名称,它也是一个单独的预处理器标记,如果它命名一个宏。这符合标准的第2.5节,其中标识符预处理器令牌和2.2,其在作为阶段4的一部分的宏扩展之前,预处理器令牌被替换为语言语法的令牌,其中发生在阶段7.

他还提到,since the Portland meeting of the committee,你可以说operator""_W,这将防止宏扩展,因为_W不再是一个单一的标识符。锵干线已经实现了这一点,并编译下面的代码片段:

#define _W _x 

int operator""_W(unsigned long long){ return 42; } 

int main(){ 
    int i = 1337_W; 
} 
+0

这会工作_string literals_以及请问'“1337” _W'工作或不预处理认为这是两个不同的令牌 –

+2

@ K-BALLO:??记住,问题与用户定义文字的字面ooerator的用法不同,它是'_W'被替换的声明。 – Xeo