是否可以在现有类中修改或“自定义”运算符?

时间:2017-04-12 00:24:15

标签: c++ inheritance operators override

我有一对成对的向量,

std::vector< std::pair<int, int> > V;

我想对这个向量进行排序,所以我写了一个快速实现。值得庆幸的是,std::pair已经定义了智能比较运算符

[[3, 1], [1, 7], [3, 5]]

分类到

[[1, 7], [3, 1], [3, 5]]

即。按每对的第一个元素排序,使用第二个元素作为决胜局。

但我真正想要的是比较减少顺序中的第二个元素。所以上面的例子应该按照

排序
[[1, 7], [3, 5], [3, 1]]

是否可以覆盖std::pair的比较运算符,以便我可以通过增加第一个和减少第二个元素来进行排序?如果没有,那么设计明智的最佳方法是什么?

我考虑从std::pair派生一个覆盖所有比较运算符的子类,但这需要reinterpret_cast std::pair<int, int>*指向我的子类的指针,这感觉非常错误。< / p>

单独的静态助手类是唯一的方法吗? (除了将所有第二个元素乘以-1之类的黑客之外,因为知道所有值都是正数。)

1 个答案:

答案 0 :(得分:1)

您应该遵循C ++库的一般设计原则,并使用比较器。有序关联容器模板(如std::set)具有可选模板参数,即设置排序顺序的比较器类。例如:

std::set<int>

为您提供一个以自然,增加的顺序对其int值进行排序的集合。迭代此库存集将迭代其值从最小值到最高值。

但这只是因为std::set确实有第二个模板参数,比较器,默认为std::less,它基本上是<运算符的包装器。这个std::set确实是:

std::set<int, std::less<int>>

(还有第三个模板参数,与本讨论的目的无关)。

如果您愿意,可以声明:

std::set<int, std::greater<int>>

然后,如果你要迭代这个集合,你会发现你将从集合中的最大值到最小值进行迭代。在所有其他方面,这个集合就像一个普通的集合。

同样,让我们​​谈谈您编写的快速排序实现。您的快速排序直接使用<运算符来比较您的std::pair。您只需重写快速排序实现,以获取指定排序顺序的附加参数(比较器)。您的快速排序实现不是仅使用重载的<运算符,而是调用比较器来比较两对。

现在,您将能够以任意顺序快速分配您的对,您可以使用一个可调用对象来指定两个任意std::pair,并计算它们的相对顺序。