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

Jus*_*tin 13 c++ language-lawyer user-defined-literals c++11

从C++ 11开始,就可以创建用户定义的文字.正如预期的那样,可以从这些文字返回复杂的结构.但是,在尝试使用此类运算符时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();
}
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会和克朗拒绝了,说他们找不到operator""_foo.bar.MSVC接受它.如果我改为写123_foo .bar(),那么所有三个编译器都接受它

谁在这?是123_foo.bar()以往任何时候都有效吗?


一些额外的信息:


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

Pas*_* By 10

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

当程序编译时,它按顺序经历9个翻译阶段.这里需要注意的关键是将源代码lexing(分离)到令牌中,然后再考虑其语义含义.

在此阶段,最大蒙克有效,即令牌被视为语法上有效的最长字符序列.例如,即使前者在语义上不有效,也不要使用x+++++ylexed .x ++ ++ + yx + ++ ++ y

那么问题是什么是最长的语法有效序列123_foo.bar.遵循预处理编号的生产规则,确切的顺序是

pp-number→pp-number identifier-nondigit→...→pp-number identifier-nondigit³→
pp-numbernondigit³→pp-number.nondigit³→...→pp-numbernondigit⁴.nondigit³→
pp-numberdigitnondigit⁴.nondigit³→...→pp-numberdigital²nondigit⁴.
nondigit³ → digit³inigigit⁴.nondigit³

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

  • @Justin问题实际上出现在你的链接段落之前.程序首先被放入预处理令牌中,而没有任何文字概念.匹配文字的标记会在稍后出现,并且是链接的内容. (4认同)