考虑以下两个用于s
的重载运算符<=>
:
#include <compare>
struct S {};
int operator<=>(S, int) { return 0; } #1
S operator<=>(S, S) { return {}; } #2
如果我将对象S
与int
进行比较,#1
将为我生成正确的运算符,所以像S{}<=0
、0
或
0<=>S{}
这样的表达式就可以了。
但如果我将一个对象
s
与其他对象s
:
S{} < S{};
则将重写为
(S{}<=>S{})<0
。由于(S{}<=>S{})
将返回另一个S
,所以我们回到原始问题:S
与int
进行比较。此时,我们没有运算符<(S,int)
,因此#1
将为我生成正确的运算符。
但令人惊讶的是,三个编译器都没有这样对我。GCC、Clang和MSVC都拒绝
S{}
并带有相同的错误消息:
no match for 'operator<' (operand types are 'S' and 'int')
这让我很沮丧。因为
#1
实际存在。为什么不在这里产生运算符的嵌套生成?标准是怎么说的?是否存在静态约束冲突?
这是错误的,尽管错误消息是相当混乱的。
[over.match.oper]/8中的规则是(强调我的):
如果通过重载解析为运算符@
选择了重写的运算符<=>
候选,则如果选定的候选是参数顺序相反的合成候选,则x@y
被解释为0@(y<=>x)
;否则,则使用选定的重写的运算符<=>
候选。在结果表达式的上下文中不考虑操作符@
的重写候选项。
表达式S{}
将解析为重写的候选
(S{}<=>S{})<0
。结果表达式将不会在其查找中考虑重写的候选项。因此,当我们执行
s{}<0
时,只需要查找一个
运算符<
,而不是
运算符<=>
。它找不到这样的东西,所以表达方式是畸形的。
<source>:8:14: error: no match for 'operator<' (operand types are 'S' and 'int')
8 | auto x = S{} < S{};
| ~~~~^~~~~
在这个意义上,错误是真的:没有匹配,特别是
operator<
与这些操作数。尽管如果错误消息中有更多的上下文来解释为什么要查找这些信息,这将会有所帮助。
我有以下结构: 我正在寻找一种算法,如何从创建一个类似父子嵌套的结构。 逻辑是这样的: 假设:列表中的第一项总是以深度=0开头 如果深度大于最后一个,它必须是最后一个的孩子 我没法让它工作。它应该是递归的,具有无限嵌套/深度级别。 谢谢你们的帮助!
问题内容: 我一直在尝试使用嵌套形式,如下所示: 但似乎我缺少了一些东西。谁能协助我该怎么做? 问题答案: 将其括在括号中: 甚至更好的是,使用适当的/ 语句(出于可维护性): 但是,正如其他人指出的那样:使用起来更简单:
C++20中有一个新的比较运算符。然而,我认为在大多数情况下,一个简单的减法效果很好: 它们的效果是一样的。我真的不明白这有什么区别。
Herb Sutter在他关于“宇宙飞船”操作员的建议(第12页底部第2.2.2节)中说: 基于及其返回类型:该模型具有主要优点,与以前针对C++的建议和其他语言的功能相比,该建议具有一些独特之处: [...] (6)效率,包括最终实现对比较的零开销抽象:绝大多数的比较总是单程通过的。唯一的例外情况是在同时支持偏序和相等的类型的情况下生成和。对于,单次传递对于实现零开销原则以避免重复相等比较至关重
< > <= >= == ~= 分别表示 小于,大于,不大于,不小于,相等,不相等 所有这些操作符总是返回 true 或 false。 对于 Table,Function 和 Userdata 类型的数据,只有 == 和 ~=可以用。相等表示两个变量引用的是同一个数据。比如: a={1,2} b=a print(a==b, a~=b) -- true, false a={1,2} b={1,2}
当我试图学习C++运算符的时候,我无意中在cppreference.com上发现了一个奇怪的比较运算符,*在如下表中: “好吧,如果这些是C++中常见的运算符,我最好学会它们”,我想。但我想要弄清楚这个谜团的一切努力都没有成功。即使在这里,在堆栈溢出,我没有运气在我的搜索。 如果有的话,这个运算符到底是做什么的? *同时CPPreference.com更新了该页,现在包含有关运算符的信息。