【问题标题】:Combining a user defined literal with a method call将用户定义的文字与方法调用相结合
【发布时间】:2013-10-16 03:52:00
【问题描述】:

我想知道为什么我不能写这样的代码:

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

GCC 4.8.1 和 Clang 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

【问题讨论】:

  • 我什至不知道C++11的这个特性,谢谢!
  • 您能否展示一个产生错误的完整示例?
  • 我添加了一个示例链接。
  • 这个版本在 clang++3.4 上编译:30_au .to_light_years();(注意空格)——这很奇怪。
  • 我并不是说插入空格使其工作很奇怪(我怀疑它会工作、尝试并成功),但奇怪的是 30_au.to_light_years() 和 @987654328 之间存在差异@ [带空格]。我同意 Jerry Coffin 的分析,即这可能是一个错误。

标签: c++ c++11 user-defined-literals


【解决方案1】:

UDL 的后缀应该是一个普通标识符(带有前导下划线),所以对我来说它看起来像一个错误。

【讨论】:

    【解决方案2】:

    这可能是词法分析器问题。用户定义的文字将被标记为单个块 - 数字加后缀是一个完整的标记。在数字文字的情况下,允许啜饮的字符包括十进制“.”。查找 pp-number:第 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...,此时,从“-”开始的剩余部分作为后缀标识符传递。

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

    我认为这实际上不是缺陷。

    【讨论】:

    • 看过第 2.10 节后我同意 - 它看起来不像是一个缺陷,虽然它是一个不便!
    • @AlexKorban:看了 §2.2/7 之后,我不同意。 “分析和翻译标记的过程有时可能会导致一个标记被一系列其他标记替换”。从单个预处理器标记开始并不意味着它在整个编译过程中保持单个标记。
    • @JerryCoffin:该注释特别提到了 14.2(“模板专业化名称”),这似乎是关于 >> 的消歧。所以在我看来,emsr 的解释仍然是正确的。我错过了什么吗?
    • @AlexKorban:是的,我想是这样——这是对一种可能性的引用,但并没有将其限制在这种可能性。
    • @JerryCoffin:我想可以这样解释。我希望您是正确的,因为这意味着我将来可能不必将文字括在括号中!
    猜你喜欢
    • 1970-01-01
    • 2013-12-25
    • 2021-07-27
    • 2021-03-03
    • 2017-04-28
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多