使用运算符覆盖排序没有得到我想要的

sort with operator overriding does not get I want

本文关键字:我想要 运算符 覆盖 排序      更新时间:2023-10-16

我正在尝试按 person.name 和年龄对人向量进行排序。因此,我尝试覆盖Person定义中的operator<,并将函子与std::sort()一起使用。

但是,我没有得到我想要的。我的期望是,人们首先按他们的名字排序,然后按他们的年龄排序。但是两种解决方案都得到了相同的结果:

che is less than xu
(wu, 30)
(che, 34)
(xu, 21)

我期望的顺序是:

(che, 34)
(wu, 30)
(xu, 21)

谁能帮助指出我犯的错误?谢谢

源代码为:

class Person{
public:
string _name;
int _age;
public:
Person(string name, int age):_name(name),_age(age){
}
bool operator<(const Person* b) const {
cout<<"Expect "<<_name <<b->_name <<"   "<< (_name < b->_name)<<endl;
if(_name != b->_name) {
return _name < b->_name;
}
else return _age<b->_age;
}
bool operator<(const Person& b) const {
if(_name!=b._name) {
cout<<_name <<" is less than "<<b._name<<endl;
return _name<b._name;
}  else return _age<b._age;
}
friend ostream& operator<<(ostream& out, const Person& b) {
out << "(" << b._name << ", " << b._age << ")"<<endl;
return out;
}
};
bool PersonCompare(const Person* a, const Person* b ){
cout<<"Expect "<<a->_name <<b->_name <<"   "<< (a->_name < b->_name)<<endl;
if(a->_name != b->_name) {
return a->_name < b->_name;
}
else return a->_age<b->_age;
}
class PersonPrint{
public:
PersonPrint(){
}
void operator()(const Person& person){
cout<<person;
}
void operator()(const Person* person){
cout<<*person;
}
};


void testSort(){
vector<Person*> personsList;
personsList.push_back(new Person("xu", 12));
personsList.push_back(new Person("che", 23));
personsList.push_back(new Person("sxy", 34));
/*std::sort(personsList.begin(), personsList.end(), [](Person* a, Person* b ){
if(a->_name!=b->_name) return a->_name<b->_name;
else return a->_age<b->_age;
}); *///This works
/* std::sort(personsList.begin(), personsList.end(), PersonCompare ) *///This works..
std::sort(personsList.begin(), personsList.end()); //This does not work
for_each(personsList.begin(), personsList.end(), PersonPrint());
}

==============这是 lambda/运算符内部的逻辑错误。将if(a._name<b._name)更改为if(a._name!=b._name)后,错误已修复。

///

我更新了代码。 为类Person添加bool operator<(const Person* b) const{},然后尝试对Person*向量进行排序。但是结果没有像我预期的那样排序,并且没有调用新添加的operator<(const Person*)。这里有什么建议吗?谢谢

您的比较函数正在踩踏未定义行为的领域。毫不奇怪,您没有看到您所期望的。 来自 std::sort's 文档

comp - 比较函数对象(即满足比较的要求(如果第一个参数为 小于(即在之前排序(第二个。

比较要求:

应用于对象的函数调用操作的返回值 类型比较,当上下文转换为布尔值时,如果 调用的第一个参数出现在严格此比较类型引起的弱排序关系,并且 否则。

您的比较函数不符合严格周排序的标准。

您可以简单地执行以下操作:

std::sort(persons.begin(), persons.end(), 
[](const Person& a, const Person& b) { return std::tie(a.name, a.age) < std::tie(b.name, b.age); })

我写了一篇关于这个的文章:你可能想参考 https://isocpp.org/blog/2016/05/strict-weak-ordering-and-stl。

编辑(基于OP的编辑(:

这不起作用,因为您已经为类提供了成员函数Person而要调用的类型是Person*。两者都是不同的类型。 您必须将PrintPerson函数的定义移到类之外,并使其在 Person 类中声明为友元方法。遗憾的是,您无法对bool operator<(Person *a, Person *b)执行相同的操作,因为运算符重载不适用于指针类型。您唯一的选择是通过比较器。