【发布时间】:2012-12-10 01:58:26
【问题描述】:
我关于名称中的下划线的问题已部分回答here,,但要么答案不完整,要么我不完全理解。
教派。 C++11标准的2.14.8.7声明了这个literal operator作为例子:
long double operator "" _w(long double);
除了声明运算符之外,标准及其示例还做了两件事,如果分开来看,每件事都是有意义的:
- 名称
_w以下划线开头;和 - 它将运算符置于全局命名空间中。
我的问题分为两部分:
- 根据the answer linked above,,名称
_w不是标识符, 或者标识符_w不是名称, 或者...好吧,我我很困惑。 - 如果
_w可以,那么大写的_W也可以——就像60.0_W,意思是60.0 瓦? 还是预处理器可能错误处理大写的版本?
毫无疑问,我和你一样,不习惯用下划线开头全局名称,这是标准教派的习惯。 17.6.4.3.2.1 似乎明确弃用。因此,如果您可以对下划线、名称和文字运算符的问题进行一些补充说明,我们将不胜感激。
【问题讨论】:
-
_W会造成麻烦,因为在字面运算符定义之前的#define _W /*anything*/会导致_W被替换。不是operator"" _W中的_W是保留的,而是实现很可能有一个像上面一样的宏_W。现在,有人可能想知道标准是否真的允许对文字运算符标识符进行宏替换,我会说是的,因为_W是一个单独的预处理器标记。 -
预处理阶段/令牌主要是第 2.2 和 2.5 条。
_W是一个 identifier,因此它是一个 preprocessing-token,如果它命名一个宏,则会在第 4 阶段进行扩展。 -
operator"" _W中的 _W 肯定是identifier,因此可以在没有警告的情况下将其重新定义为宏。这不会影响27_W中的_W(这不是预处理令牌),但我认为如果无法定义operator"",那将是一种冷酷的安慰。 13.5.8 (8) 表明定义operator ""_W(没有空格)是不合法的,因为 _W 在该上下文中不是标识符。另一方面,最后一个构造,afaics,不能在格式良好的程序中使用,这使得在不影响任何现有正确代码的情况下将其添加到语法中是可行的。 C++1y? -
Johannes Schaub - litb 在 cmets 关于该答案的建议中,name 包含完整的
operator ""部分(他说“总而言之,他的名字以o而不是_)。_w是标识符,而operator "" _w是名称。或者至少这是我从问题中得到的... -
还想补充一点,Luc Danton 非常清楚地说明了哪个部分是名称:“literal-operator-id 是一个名称。它的标识符部分不是。” (根据他的回答,literal-operator-id 被定义为:
operator "" identifier,其中identifier是_w)。我也问过_W,看来这个版本确实可能有问题。
标签: c++ c++11 operator-overloading