是否基于其他操作符自动提供任何c++操作符重载
Are any C++ operator overloads provided automatically based on others?
假设我正在编写一个int
包装器,并且需要提供每个操作符重载。作者必须列出每一个单独的,或者它可以自动生成任何基于作者所提供的?编译器是否可以从现有的操作符中推断出任何新的自定义操作符?
如果我定义了operator==
,它会自动给我一个operator!=
吗?反之亦然?
如果我定义了operator++()
,我是否可以免费获得operator++(int)
?反之亦然?
+=
类型的业务呢?是否可以将现有的operator+
和operator=
的定义结合起来生成operator+=
?从理论上讲,这应该是可能的,但事实是这样吗?
同样的问题对于>=
到<
等,或者我必须完全列出>
, >
, >=
, <=
的定义吗?
在核心语言中,各种操作符是独立的。有些操作符是根据其他操作符定义的,但如果操作符调用的重载解析失败,则不会尝试用其他操作符表示该调用。当需要时,程序员可以很容易地表达它(相反,关闭这种机制可能会更困难)。
在std::rel_ops
中有一组客户端代码可以使用的关系操作符重载,它们是根据<
和==
定义的。
可以很容易地编写一个mixin类,它根据<
和==
或三值compare
函数提供关系运算符。这就是奇怪循环模板模式的最初动机,称为Barton-Nackman技巧。
No.
c++在核心语言中没有推理规则,所以即使定义说+
,它也不假设+=
…它们(就语言而言)完全无关。
考虑标准库中的<<
(左位移位操作符)被重载为表示"输出到流"…只是因为它的外观和合理的优先级和结合性。
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 <=>c++中的操作符?
在Ubuntu 20.04, GCC 10.2.0上测试
c++ 20增加了一个特性,允许语言对关系运算符(<
, >
, <=
, >=
)和相等运算符(==
和!=
)执行类似的操作。
当使用相等操作符时,系统可以尝试反转操作数的顺序(用于不同类型的相等性测试),也可以为结果取反,以找到合适的operator==
过载。也就是说,如果你只实现operator==
对A
和B
的相等性测试,这也将允许你对B
和A
进行相等性测试,以及对它们进行不等性测试。
==
运算符,它将b != a
转换为!(a == b)
。
对于<=>
,它以相同的方式应用于所有关系操作符(但不是相等操作符)。系统将根据需要将a < b
重写为(a <=> b) < 0
或(b <=> a) > 0
,以找到匹配的重载<=>
操作符。
此外,您可以= default
任何比较操作符,它按照子对象的顺序对所讨论的类型的子对象进行比较(您只能默认对同一类型的比较)。如果您默认使用==
操作符,那么根据上述规则,您将有效地获得!=
。如果默认为<=>
,则可以通过重写获得所有关系操作符。
如果你默认<=>
而不默认==
,那么系统也会生成一个默认的==
,所以默认的<=>
单独给你所有的比较运算符。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何在不产生任何垃圾的情况下获得C中的像素
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- C++映射有2个键,这样任何1个键都可以用来获取值
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- RtlCaptureStackBackTrace未捕获任何帧
- 链表c++插入,所有情况都已检查,但没有任何工作
- C++模板函数,用于比较任何无符号整数和有符号整数
- Arduino millis() - millis() 怎么能等于 0 以外的任何东西?
- 尝试摆脱任何堆内存分配
- 是否有任何C++功能可以对地图进行排序?
- 打印时有二叉树问题.用户输入不打印任何内容
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 在C++行尾写一个分号或多个分号是否会改变任何内容
- C++类型特征,以查看是否可以<uint32_t>对类型"K"的任何变量调用"static_cast(k)"
- 任何重载操作符()的静态检测
- 是否基于其他操作符自动提供任何c++操作符重载
- 是否有方法为任何指针类型定义转换操作符
- c++:删除==或任何其他特定类型的操作符