假设我正在编写int
包装器,需要提供每个运算符的重载。作者必须列出每一个,还是可以根据作者提供的内容自动生成任何一个?编译器是否可以从现有的运算符中推断出任何新的自动定义运算符?
如果我定义operator==
,它会自动给我operator!=
吗?反之亦然?
如果我定义operator++()
,我是免费获得operator++(int)
吗?反之亦然?
+=
类型的业务怎么样?是否可以将operator+
的现有定义与operator=
结合起来生成operator+=
?从理论上讲它应该是可能的,但是它呢?
>=
与<
等相同的问题,或者我是否必须完整列出>
,>
,>=
,{{的定义1}}?
答案 0 :(得分:4)
在核心语言中,各种运营商是独立的。有些是根据其他方面定义的,但如果运算符调用的重载解析失败,则不会尝试用其他运算符表示该调用。如果需要,可以很容易地由程序员表达(相反,关闭这样的机器,可能会更困难)。
客户端代码可以使用std::rel_ops
中的一组关系运算符重载,以<
和==
定义。
您可以轻松编写一个mixin-class,它根据<
和==
或三值compare
函数提供关系运算符。这是Curiously Recurring Template Pattern的原始动机,称为Barton-Nackman trick。
答案 1 :(得分:2)
没有
C ++在核心语言中没有推理规则,所以即使定义说+
它也不会假设+=
...它们只是(如就语言而言完全不相关。
考虑到标准库中的<<
(左移位运算符)已经过载,意味着“输出到流”...只是因为外观和合理的优先级和关联性。
答案 2 :(得分:0)
C ++ 20运算符<=>
似乎在C ++ 20中不推荐使用std::rel_ops
,默认情况下<=>
将自动免费提供==, !=, <, >, <=, >=
。
改编自https://en.cppreference.com/w/cpp/language/default_comparisons:
main.cpp
#include <cassert>
#include <compare>
#include <set>
struct Point {
int x;
int y;
auto operator<=>(const Point&) const = default;
};
int main() {
Point pt1{1, 1}, pt2{1, 2};
// Just to show it Is enough for `std::set`.
std::set<Point> s;
s.insert(pt1);
// Do some checks.
assert(!(pt1 == pt2));
assert( (pt1 != pt2));
assert( (pt1 < pt2));
assert( (pt1 <= pt2));
assert(!(pt1 > pt2));
assert(!(pt1 >= pt2));
}
编译并运行:
sudo apt install g++-10
g++-10 -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
更多详细信息,请访问:What is the <=> operator in C++?
在Ubuntu 20.04,GCC 10.2.0上进行了测试。
答案 3 :(得分:0)
C ++ 20添加了一项功能,使该语言可以为关系(<
,>
,<=
,{{1} })和相等运算符(>=
和==
)。
使用相等运算符时,系统可以尝试反转操作数的顺序(用于不同类型的相等性测试),并取反结果以找到适当的!=
重载。也就是说,如果您仅实现operator==
来与operator==
进行相等性测试A
,这也将允许您对B
进行相等性测试B
和不相等性测试他们也是。
请注意,编译器不是为您生成运算符 functions 。相反,它正在修改调用操作员的实际位置。也就是说,它将A
转换为b != a
以便找到合适的!(a == b)
运算符。
对于==
,它以几乎相同的方式应用于所有关系运算符(但不是等于运算符)。系统将根据需要将<=>
重写为a < b
或(a <=> b) < 0
,以找到匹配的重载(b <=> a) < 0
运算符。
此外,您可以<=>
进行子对象明智的任何比较运算符,以便对所讨论类型的子对象进行顺序比较(您只能默认相同类型的比较)。如果您默认使用= default
运算符,则按照上述规则,您也可以有效地获得==
。如果您默认使用!=
,则可以通过重写获得所有关系运算符。
如果您默认<=>
而没有默认<=>
,则系统也会 生成默认==
,因此默认{仅{1}}就可以为您提供所有比较运算符。