2013-10-16 26 views
6

我不知道为什么我不能这样写代码:结合用户定义的字面在方法调用

constexpr double radius = 27_km.to_miles(); // _km returns Distance instance 
              // which has to_miles() 

两个GCC 4.8.1和3.4锵抱怨说,他们无法找到文本操作operator"" _km.to_miles除非我包裹在括号27_km

constexpr double radius = (27_km).to_miles(); // fine 

通过我的标准的第2.14.8的读数,UDL后缀不能包含一个时期,那么,为什么编译器解析这样的代码?它们是正确的还是错误?

编辑:你可以看到一个完整的例子(使用不同的UDL和方法名)在这里:http://ideone.com/rvB1pk

+0

我甚至都不知道C++ 11的这个特性,谢谢! – orlp

+1

你能否展示一个产生错误的完整例子? –

+0

我已经添加了一个示例链接。 –

回答

2

这可能是一个词法分析器问题。用户定义的文字将被标记为单个块 - 数字加后缀是一个整体标记。在数字文字的情况下,允许文字上的字符包括小数点'。'。查找pp数字:第2.10节 - 标准的latest draft中的lex.ppnumber。演练如何预处理器(词法分析器)将扫描令牌:

30_au.to_light_years() 

digit 
digit 
identifier-nondigit 
. 
identifier-nondigit x 14 
(breaks the spell 

所以预处理看到30_au.to_light_years作为一个大奇特(浮点)数。然后后来,在数字解析阶段,我们看到digit, digit, identifier-nondigit...在这一点上,从' - '开始的剩余部分作为后缀标识符传递。

请记住,数字文字在预处理器标记化后的之后被解释为

我觉得这实际上是不是的一个缺陷。

+0

看过第2.10节之后,我同意 - 它看起来不像是一个缺陷,虽然这是一个不便! –

+0

@AlexKorban:在看过§2.2/ 7后,我不同意。 “分析和翻译令牌的过程偶尔会导致一个令牌被一系列其他令牌所取代”。作为单个预处理器标记开始并不意味着它在整个编译期间保持单个标记。 –

+0

@JerryCoffin:该说明特别提及14.2(“模板专业化的名称”),这似乎与“消除歧义”有关。所以在我看来,emsr的解释仍然是正确的。我错过了什么吗? –

3

的UDL的后缀应该是一个正常的标识符(用前导下划线),所以它看起来像给我一个错误。