<=> 在 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<=>();
}
其他所有内容仍然涉及通过名称明确提及比较函数 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-expression 或 shift-expression,它们都是 expression 的限制排序。但是没有语法规则允许任何 表达式 以 >
或 >>
或 >=
或 >>=
.[=48= 开头]
只剩下语法符号 运算符,仅在:
中找到
operator-function-id:
operator
operator
这表明关键字 operator
必须紧接在 <=
之前,这可能会在 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]
我试图找出如何在 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<=>();
}
其他所有内容仍然涉及通过名称明确提及比较函数 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-expressionoperator:
<=
语法符号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-expression 或 shift-expression,它们都是 expression 的限制排序。但是没有语法规则允许任何 表达式 以 >
或 >>
或 >=
或 >>=
.[=48= 开头]
只剩下语法符号 运算符,仅在:
中找到operator-function-id:
operator
operator
这表明关键字 operator
必须紧接在 <=
之前,这可能会在 C++20 中作为 <=>
的一部分结束。