<=> 在 c++20 之前的代码中的合法外观

Legitimate appearances of <=> in pre-c++20 code

本文关键字:代码 外观 lt gt c++20      更新时间:2023-10-16

在魔杖盒中胡闹 我发现如果 clang 看到<=>出现在 C++17 或更早版本中,它实际上会发出警告。

warning: '<=>' is a single token in C++2a; add a space to avoid a change in behavior [-Wc++2a-compat]

我试图弄清楚如何编写 C++17 中字符序列<=>的合法用例,但我想出的都感觉非常做作。最可能的示例 (imo) 涉及使用模板:

struct A {
bool operator<=(A) const { return true; }
};
template <auto Cmp>
void f() { }
int main() {
f<&A::operator<=>();
}

现场示例

其他所有内容仍然涉及按名称operator<=明确提及比较函数。是否有更常见的<=>外观,我无法想象这会促使 clang 开发人员添加此警告?

还有其他一些可能的语法不一定涉及这样的模板参数。 例如

class A {};
bool operator<=(A,A) { return true; }
class B {};
bool operator>(bool(*)(A,A), B) { return false; }
int main()
{
B b;
return operator <=> b;
}

但确实,所有这些示例在<=>出现之前都有关键字operator

证明这种说法的唯一方法是对整个C++语法进行详尽的搜索,方便地显示在 C++17 标准和其他一些标准版本的附录 A 中的一个地方。

首先,请注意,由于最大蒙克规则,如果解析了先前预处理器令牌之后的下一个源字符<=>,则 C++17 及更早版本将始终将第一个令牌视为<=。 下一个令牌实际上可能是>>>>=>>=

涉及令牌<=的唯一语法规则是:

折叠运算符

<=

关系表达式

关系表达<=移位表达

操作员

<=

语法符号折叠运算符仅用于:

折叠表达式

(投射表情折叠运算符... )

( ...折叠运算符演员表达)

(强制表达折叠运算符...折叠运算符强制表达)

因此,作为折叠运算符<=后面必须跟有...令牌(当然不是>>>>=>>=),或者转换表达式。 无论是作为折叠运算符还是在关系表达式中,<=标记后都可以跟着强制转换表达式移位表达式,这两者都是受限制的表达式。 但是没有语法规则允许任何表达式>>>>=>>=开头。

这只剩下语法符号运算符,只能在以下位置找到:

运算符函数 ID

operator运算符

这表明关键字operator必须紧挨着<=,而最终可能会成为 C++20 中<=>的一部分。