前几天使用list的排序功能,出现了一点问题,来总结一下。
定义一个简单的节点类,包含一个字符串和一个整数,并重载了小于操作,根据整数的大小进行比较。
class Node { public: Node(string nm,int i) { name = nm; id = i; } void Print() { cout << name << ":" << id << endl; } friend bool operator < (const Node& n1,const Node& n2) { cout << "comparing:" << endl; return (n1.id<n2.id); } public: int id; string name; };
然后创建了一个测试的结构,
把一些Node节点的地址放入list中,我一般是这样用的,因为有时候在一个地方用创建了这些节点,在另外的一些地方要用这些节点,
如果创建的时候不使用new的话,把他们存入list之后,在其他地方就不能再使用,所以就只能用new创建了,然后把指针放入list。
代码如下,
class NodeList { public: NodeList() { Node* n1 = new Node("abc",3); Node* n2 = new Node("efb",5); Node* n3 = new Node("ac",1); Node* n4 = new Node("a",0); Node* n5 = new Node("4",4); nodes.push_back(n1); nodes.push_back(n2); nodes.push_back(n3); nodes.push_back(n4); nodes.push_back(n5); } void Print() { list<Node*>::iterator it = nodes.begin(); for(;it!=nodes.end();it++) { (*it)->Print(); } } void Test() { Print(); nodes.sort(); cout << "\nafter sort:" << endl; Print(); struct cmp_node cmpnode; nodes.sort(cmpnode); cout << "\nafter sort(cmp_node):" << endl; Print(); } public: list<Node*> nodes; };
在使用list sort的时候,可以使用默认参数,也可以传递一个比较函数,所以又定义了一个Node的比较函数,放在struct里面,
struct cmp_node { public: bool operator () (const Node* n1, const Node* n2) const { return ((n1->id)<(n2->id)); } };
最后进行测试,调用nodeList的Test函数就可以了。期望后两次的结果都是排好序的?但结果确实只有最后的一个是排好序的,也就是第一次没有传递比较函数作为参数的sort没有对list排序。这个不知道是什么原因。
来说一下为什么要把新定义的比较函数放在一个结构体里面。
在C/C++里面,函数不是对象,不能作为参数来传递,所以把要传递的函数放在一个对象里面,这里是放在一个struct里面,按理说放在一个class里面作为public函数也是可以的,没有进行测试过,记得使用unordered_map传递hash函数的时候,也是类似的情况,当时使用的后一种方法。
需要注意的是,在结构体里面定义比较函数的时候,不再是重载小于号,而是一对小括号,然后参数应该是放在list里面的数据类型,是节点指针。
总觉得把指针放在list里面好像很别扭的,希望大家能指导下这种情况下的list的用法。