<=> 在 c++20 之前的代码中的合法出现

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

在 wandbox 中乱搞我发现如果 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 中编写字符序列 <=> 的合法用例,但我想出了 all feel very contrived。最可能的示例 (imo) 涉及使用模板:

struct A {
  bool operator<=(A) const { return true; }
};

template <auto Cmp>
void f() { }

int main() {
  f<&A::operator<=>();
}

live example

其他所有内容仍然涉及通过名称明确提及比较函数 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 中的一个地方。

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

涉及标记 <= 的唯一语法规则是:

fold-operator:

    <=

relational-expression:

    relational-expression <= shift-expression

operator:

    <=

语法符号fold-operator仅用于:

fold-expression:

    ( cast-expression fold-operator ... )

    ( ... fold-operator cast-expression )

    ( cast-expression fold-operator ... fold-operator cast-expression )

因此,作为 fold-operator<= 必须后跟 ... 标记(肯定不是 >>>>=>>=),或 cast-expression。无论是作为 fold-operator 还是在 relational-expression 中,<= 标记后面都可以跟 cast-expressionshift-expression,它们都是 expression 的限制排序。但是没有语法规则允许任何 表达式 >>>>=>>=.[=48= 开头]

只剩下语法符号 运算符,仅在:

中找到

operator-function-id:

    operator operator

这表明关键字 operator 必须紧接在 <= 之前,这可能会在 C++20 中作为 <=> 的一部分结束。