指针集中元素的顺序

Order of elements in set of pointers

本文关键字:顺序 元素 集中 指针      更新时间:2023-10-16

为什么即使我已经注释了A::operator<,也会编译以下代码。我想知道在没有<运算符的情况下如何按升序打印以下代码的输出。如何将顺序更改为降序?(注意:如果我使用A而不是A*,除非我提供A::operator<的定义,否则不会编译此代码)

#include <iostream>
#include <set>
using namespace std;
class A
{
public:
A(int v):x(v){}
virtual ~A(){}
int x;
/*bool operator<(const A &a) const
{
return x > a.x;
}*/
};
int main()
{
set<A*> numbers;
A* a1 = new A(1);
A* a2 = new A(2);
A* a3 = new A(3);
numbers.insert(a2);
numbers.insert(a3);
numbers.insert(a1);
for(set<A*>::iterator itr = numbers.begin();itr!=numbers.end();itr++)
{
cout << (*itr)->x << endl;
}
// output: 1 2 3
return 0;
}

编译代码是因为您有一组指针。由于集合包含指针,并且您的运算符不比较指针,而是比较A类型的对象,因此集合不需要它。有一个现有的指针小于比较运算符,这是您的集合中使用的运算符。

您可以通过提供自己的比较器来实现严格的弱排序来更改顺序:

struct APtrComp
{
bool operator()(const A* lhs, const A* rhs) const  { /* implement logic here */ }
};

并将其用作第二个模板参数实例化您的集合。

set<A*, APtrComp> numbers;

你有一组指针。 通常指针按递增顺序分配。 指针具有默认的<运算符。 所以这就是它编译和工作的原因。

附言,无论值是什么,它都会按此顺序打印 A1 A2 A3 的值:

...
A* a1 = new A(9);
A* a2 = new A(5);
A* a3 = new A(1);
...
// output: 9 5 1

如果你记得你的指针算术,所有点都会被赋予一组运算符,以便在操作中使用(包括运算符<)。您的集合将使用此默认运算符 <。

据我了解,您想知道为什么即使您没有operator<,代码也会使用A*进行编译,以及如何将顺序从升序更改为降序。

它之所以编译,是因为它使用带有指针地址的operator<
cout << (*itr)->x << endl;
更改为cout << (*itr)->x << ' ' << *itr << endl;,您将很容易看到它:)

如果您使用的是set<A>,则代码在没有operator<的情况下无法编译是正常的。它不知道要比较什么才能插入排序的成员。所以你必须提供那个操作员!

如果要继续使用指针,可以使用@juanchopanza提供的代码。

相关文章: