16

在 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 中编写一个合法的字符序列用例,但我想出的东西都觉得很做作。最可能的示例(imo)涉及使用模板:

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

template <auto Cmp>
void f() { }

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

活生生的例子

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

4

1 回答 1

17

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

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 和其他一些标准版本的一个地方。

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

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

折叠运算符

    <=

关系表达式

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

运营商

    <=

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

折叠表达式

    ( cast-expression 折叠运算符 ... )

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

    ( cast-expression 折叠运算符 ... fold-operator cast-expression )

因此,作为fold-operator<=必须后跟...令牌(肯定不是>or>>>=or >>=)或cast-expression。无论是作为折叠运算符还是在关系表达式中,<=记号后面都可以跟一个强制转换表达式移位表达式,它们都是受限类型的表达式。但是没有语法规则允许任何表达式>or>>>=or开头>>=

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

操作员功能ID

    operator 操作员

这表明关键字operator必须紧接在which 之前,而在 C++20<=中可能最终成为 a 的一部分。<=>

于 2018-03-14T01:22:38.477 回答