用户定义的数字文字可以紧跟一个点吗? [重复]

问题描述 投票:13回答:1

这个问题在这里已有答案:

从C ++ 11开始,就可以创建User Defined Literals了。正如预期的那样,可以从这些文字返回复杂的结构。但是,当尝试使用123_foo.bar()这样的运算符时:

struct foo {
    int n;
    int bar() const { return n; }
};

constexpr foo operator ""_foo(unsigned long long test)
{
    return foo{ static_cast<int>(test) };
}

int main() {
    return 123_foo.bar();
}

GCC and Clang reject it,说他们找不到operator""_foo.bar。 MSVC接受它。如果我改为写123_foo .bar()all three compilers accept it

谁在这? 123_foo.bar()有效吗?


一些额外的信息:


我倾向于认为这是一个GCC和Clang错误,因为.不是有效标识符的一部分。

c++ c++11 language-lawyer user-defined-literals
1个回答
10
投票

TLDR Clang和GCC是正确的,你不能在用户定义的整数/浮点字面值之后写一个.,这是一个MSVC错误。

程序编译后,按顺序通过9 phases of translations。这里需要注意的关键是将源代码lexing(分离)到令牌中,然后再考虑其语义含义。

在这个阶段,maximal munch生效,也就是说,令牌被视为语法上有效的最长字符序列。例如,x+++++y被定为x ++ ++ + y而不是x + ++ ++ y,即使前者在语义上没有效力。

那么问题是123_foo.bar最长的语法有效序列是什么。在production rules之后的预处理数字,确切的顺序是

pp-number→pp-number identifier-nondigit→...→pp-number identifier-nondigit³→ pp-numbernondigit³→pp-number。 nondigit³→...→pp-numbernondigit⁴。 nondigit³→ pp-数字nondigit⁴。 nondigit³→...→pp-numberdigital²nondigit⁴。 nondigit³→ digit³nondigit⁴。 nondigit³

哪个解析为123_foo.bar,如错误消息中所示

© www.soinside.com 2019 - 2024. All rights reserved.