在pre-c ++ 20代码中合法出现<=>

Rya*_*ing 15 c++ spaceship-operator c++17 c++20

在wandbox中乱搞我发现clang实际上会发出警告,如果它看到<=>出现在C++ 17或更早版本中.

warning: '<=>' is a single token in C++2a; add a space to avoid a change in behavior [-Wc++2a-compat]
Run Code Online (Sandbox Code Playgroud)

我试图弄清楚如何<=>在C++ 17中编写一个合法的字符序列用例,但我想出的都觉得非常有用.最可能的例子(imo)涉及使用模板:

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

template <auto Cmp>
void f() { }

int main() {
  f<&A::operator<=>();
}
Run Code Online (Sandbox Code Playgroud)

实例

其他所有内容仍涉及按名称明确提及比较功能operator<=.是否有一个更常见的外观<=>,我没想到哪个会激励clang开发人员添加此警告?

asc*_*ler 16

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

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;
}
Run Code Online (Sandbox Code Playgroud)

但是所有这些例子确实operator在出现之前就有关键字<=>.

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

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

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

fold-operator:

    <=

关系表达式:

    关系表达式 <= 移位表达式

运营商:

    <=

语法符号fold-operator仅用于:

fold-expression:

    ( cast-expression fold-operator ... )

    ( ... fold-operator cast-expression )

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

因此,作为折叠运算符,<=必须后跟...令牌(当然不是>>>>=>>=)或者演员表达式.无论是作为折叠运算符还是作为关系表达式,<=令牌后面都可以跟一个cast-expressionshift-expression,它们都是受限制的表达式.但是没有语法规则允许任何表达式>>>>=或开头>>=.

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

operator-function-id:

    operator 操作者

这表明关键字operator必须紧接在<=它之前,而不是最终作为<=>C++ 20的一部分.