19

为什么即使我已经注释了以下代码也会编译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;
}
4

4 回答 4

29

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

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

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

并使用它作为第二个模板参数来实例化您的集合。

set<A*, APtrComp> numbers;
于 2012-11-05T14:28:42.600 回答
3

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

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

...
A* a1 = new A(9);
A* a2 = new A(5);
A* a3 = new A(1);
...
 // output: 9 5 1
于 2012-11-05T14:32:17.170 回答
1

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

于 2012-11-05T14:34:17.270 回答
0

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

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

没有operator<使用set<A>. 它不知道要比较什么才能插入已排序的成员。所以你必须提供那个运营商!

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

于 2012-11-05T15:08:22.363 回答