C++ 使用运算符重写进行排序不能得到我想要的结果

C++ 使用运算符重写进行排序不能得到我想要的结果,c++,operator-overloading,functor,C++,Operator Overloading,Functor,我正在尝试按person.name和age对person向量进行排序。因此,我试图覆盖操作符您的比较函数正在践踏未定义行为的领域。难怪你没有看到你所期望的。 从 comp-比较函数对象(即满足 返回的比较要求​如果第一个参数为 少于第二个(即在第二个之前订购) 要求: 应用于对象的函数调用操作的返回值 类型比较,当上下文转换为bool时,如果 调用的第一个参数出现在strict中的第二个参数之前 此比较类型导致的弱排序关系,为false 否则 您的比较函数不符合严格的周排序标准 您可以简单地执行

我正在尝试按person.name和age对person向量进行排序。因此,我试图覆盖
操作符您的比较函数正在践踏未定义行为的领域。难怪你没有看到你所期望的。
从

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); })