7

假设我正在编写一个int包装器,并且需要提供每个运算符重载。作者必须列出每一个,还是可以根据作者提供的内容自动生成?编译器可以/是否从现有的运算符中推断出任何新的自动定义运算符?

如果我定义operator==,它会operator!=自动给我一个吗?或相反亦然?

如果我定义operator++(),我可以operator++(int)免费获得吗?或相反亦然?

+=打字业务怎么样?它可以结合现有的operator+with定义吗operator=定义来生成operator+=吗?理论上它应该是可能的,但它是可能的吗?

>=to等的相同问题<,还是我必须完整列出>, >, >=,的定义<=

4

4 回答 4

4

在核心语言中,各种运算符是独立的。有些是根据其他运算符定义的,但是如果运算符调用的重载解析失败,则不会尝试根据其他运算符来表达该调用。当需要时,程序员可以很容易地表达出来(相反,关闭这种机器可能会更困难)。

std::rel_ops客户端代码可以使用一组关系运算符重载,根据<和定义==

您可以轻松地编写一个 mixin 类,该类以<and==或三值compare函数的形式提供关系运算符。这就是奇怪重复模板模式的最初动机,称为Barton-Nackman 技巧

于 2015-09-28T06:30:18.087 回答
3

不。

C++在核心语言中没有推理规则,所以即使定义说它+也不假设+=......它们只是(就语言而言)完全不相关。

考虑到<<标准库中的(左位移位运算符)已被重载以表示“输出到流”......只是因为外观以及合理的优先级和关联性。

于 2015-09-28T06:29:45.050 回答
1

C++ 20 运算符<=>

看来,对于 C++20,std::rel_ops已弃用,默认设置<=>将自动==, !=, <, >, <=, >=免费提供。

改编自https://en.cppreference.com/w/cpp/language/default_comparisons

主文件

#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

更多详细信息:什么是 C++ 中的 <=> 运算符?

在 Ubuntu 20.04、GCC 10.2.0 上测试。

于 2020-11-10T15:20:20.050 回答
1

C++20 添加了一项功能,允许语言对关系运算符 ( , , , ) 和相等运算符 ( and ) 执行类似的操作。<><=>===!=

使用相等运算符时,系统可以尝试反转操作数的顺序(用于不同类型的相等测试)以及否定结果以找到适当的operator==重载。也就是说,如果您只使用 实现operator==相等性测试AB这也将允许您使用 进行相等性测试BA并且也可以对它们进行不等式测试。

请注意,编译器不会为您生成运算符函数。相反,它修改了调用操作符的实际位置。也就是说,它变成b != a!(a == b)为了找到合适的==运算符。

对于<=>,它以几乎相同的方式应用于所有关系运算符(但不是相等运算符)。系统将重写a < b(a <=> b) < 0(b <=> a) > 0根据需要查找匹配的重载<=>运算符。

此外,您可以= default使用任何按子对象执行的比较运算符,以便比较相关类型的子对象(您只能默认比较相同类型)。如果您默认==操作员,那么按照上述规则,您也可以有效地得到!=。如果您 default <=>,您将通过重写获得所有关系运算符。

如果你默认<=> 没有defaulting ==,那么系统也会生成一个 default ==,所以<=>只有 defaulting 会给你所有的比较运算符。

于 2020-11-10T16:07:07.563 回答