C++ 使用运算符重写进行排序不能得到我想要的结果
我正在尝试按person.name和age对person向量进行排序。因此,我试图覆盖C++ 使用运算符重写进行排序不能得到我想要的结果,c++,operator-overloading,functor,C++,Operator Overloading,Functor,我正在尝试按person.name和age对person向量进行排序。因此,我试图覆盖操作符您的比较函数正在践踏未定义行为的领域。难怪你没有看到你所期望的。 从 comp-比较函数对象(即满足 返回的比较要求如果第一个参数为 少于第二个(即在第二个之前订购) 要求: 应用于对象的函数调用操作的返回值 类型比较,当上下文转换为bool时,如果 调用的第一个参数出现在strict中的第二个参数之前 此比较类型导致的弱排序关系,为false 否则 您的比较函数不符合严格的周排序标准 您可以简单地执行
操作符您的比较函数正在践踏未定义行为的领域。难怪你没有看到你所期望的。
从
comp-比较函数对象(即满足
返回的比较要求如果第一个参数为
少于第二个(即在第二个之前订购)
要求:
应用于对象的函数调用操作的返回值
类型比较,当上下文转换为bool时,如果
调用的第一个参数出现在strict中的第二个参数之前
此比较类型导致的弱排序关系,为false
否则
您的比较函数不符合严格的周排序标准
您可以简单地执行以下操作:
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); })
排序(persons.begin(),persons.end(),
[](constperson&a,constperson&b){return std::tie(a.name,a.age)
我写了一篇关于这一点的文章:你可能想参考一下
编辑(基于OP的编辑):
这不起作用,因为您为Person
类提供了成员函数,而您要调用的类型是Person*
。两者都是不同的类型。
您必须将
PrintPerson
函数的定义移到类外,并使其在Person类中声明为友元方法。不幸的是,您不能对bool执行同样的操作operator@SamVarshavchik这个问题实际上是一个基本的逻辑错误。是的,调试器会很好,但它不是必需的。只要名字不小于第二个,你就可以按年龄排序,包括当它更大的时候。将操作符更改为如果(name==b.name)返回age理想情况下,将其更改为std::tie(a.name,a.age)
,它完成了@Jerry上面所说的一切,但保存了所有的样板。@SamVarshavchik,std::tie
并不复杂,也不是“高级模板技术”,这个问题是一个基本的逻辑错误。如果可能的话,我喜欢在进入调试器之前解决逻辑错误,因为这样通常可以节省我几个小时之后的时间。使用<代码> STD::TIG/<代码>将样板缩小到1行,并且它有效地使用了现代C++,而不需要模板元编程。SamVarshavchik同意OP可能不想知道STD::TIA-我认为亚力山大是向我推荐的,而不是OP。我个人认为它非常聪明…谢谢。最后我用另一个类似的问题更新了我的帖子。这是覆盖bool操作库的正确方法。关于“运算符重载不适用于指针类型”,您的意思是这仅指运算符吗运算符重载的标准是,如果函数位于命名空间级别,则至少有一个参数应为类或枚举类型。运算符重载仍然适用于成员函数的指针类型。
(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());
}
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); })