用户定义的数字文字后可以紧跟一个点吗?
Can user defined numeric literals be immediately followed by a dot?
从 C++11 开始,可以创建 User Defined Literals。正如预期的那样,可以从这些文字中 return 复杂结构。但是,当尝试使用 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, saying they can't find an operator""_foo.bar
. MSVC accepts it. If I instead write 123_foo .bar()
, all three compilers accept it
谁在这儿? 123_foo.bar()
是否有效?
一些额外信息:
- 三个都接受 string literals
std::chrono
literals 也存在此问题
我倾向于认为这是一个 GCC 和 Clang 错误,因为 .
不是有效标识符的一部分。
TLDR Clang 和 GCC 是正确的,您不能在用户定义 integer/floating 文字后立即编写 .
,这是一个 MSVC 错误。
当一个程序被编译时,它会按顺序经过9 phases of translations。这里要注意的关键是在考虑其语义含义之前将源代码词法化(分离)为标记。
在这个阶段,maximal munch生效,即token被认为是语法上有效的最长字符序列。例如 x+++++y
被词法化为 x ++ ++ + y
而不是 x + ++ ++ y
即使前者在语义上无效。
接下来的问题是 123_foo.bar
的最长句法有效序列是什么。在 production rules 之后的预处理编号,确切的顺序是
pp-number → pp-number identifier-nondigit → ... → pp-number identifier-nondigit³ →
pp-number nondigit³ → pp-number . nondigit³ → ... → pp-number nondigit⁴ . nondigit³ →
pp-number digit nondigit⁴ . nondigit³ → ... → pp-number digit² nondigit⁴ . nondigit³ →
digit³ nondigit⁴ . nondigit³
解析为 123_foo.bar
,如错误消息中所示
从 C++11 开始,可以创建 User Defined Literals。正如预期的那样,可以从这些文字中 return 复杂结构。但是,当尝试使用 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, saying they can't find an operator""_foo.bar
. MSVC accepts it. If I instead write 123_foo .bar()
, all three compilers accept it
谁在这儿? 123_foo.bar()
是否有效?
一些额外信息:
- 三个都接受 string literals
std::chrono
literals 也存在此问题
我倾向于认为这是一个 GCC 和 Clang 错误,因为 .
不是有效标识符的一部分。
TLDR Clang 和 GCC 是正确的,您不能在用户定义 integer/floating 文字后立即编写 .
,这是一个 MSVC 错误。
当一个程序被编译时,它会按顺序经过9 phases of translations。这里要注意的关键是在考虑其语义含义之前将源代码词法化(分离)为标记。
在这个阶段,maximal munch生效,即token被认为是语法上有效的最长字符序列。例如 x+++++y
被词法化为 x ++ ++ + y
而不是 x + ++ ++ y
即使前者在语义上无效。
接下来的问题是 123_foo.bar
的最长句法有效序列是什么。在 production rules 之后的预处理编号,确切的顺序是
pp-number → pp-number identifier-nondigit → ... → pp-number identifier-nondigit³ →
pp-number nondigit³ → pp-number . nondigit³ → ... → pp-number nondigit⁴ . nondigit³ →
pp-number digit nondigit⁴ . nondigit³ → ... → pp-number digit² nondigit⁴ . nondigit³ →
digit³ nondigit⁴ . nondigit³
解析为 123_foo.bar
,如错误消息中所示