2017-07-07 45 views
0

我想通过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()); 
} 

============== 它是λ-/操作者的内部的逻辑错误。将if(a._name<b._name)更改为if(a._name!=b._name)后,错误得到修复。

/////////////////////////////////////

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

+0

你的错误是没有使用你的调试器一次一行地遍历你的代码,并检查所有变量的值,并检查执行代码的逻辑。使用调试器可以简单地识别此问题,并且知道如何使用调试器是每个C++开发人员所需的技能。 –

+1

@SamVarshavchik,这个问题确实是一个基本的逻辑错误。调试器是好的,但它不是必需的。 –

+3

随着年龄的增长,您随时订购的第一个名字不少于第二个名字 - 包括大的时候。将运算符<更改为if(name == b.name)return age

回答

0

您的比较函数正在践踏未定义行为的领域。毫不奇怪,你没有看到你的期望。 从std::sort's documentation

排版 - 比较函数对象(即满足比较的 要求的对象),如果所述第一参数大于(即之前订购)的第二较少 返回true。

Compare要求:

如果 出现真正应用于对象类型的 比较,当上下文转换为bool函数调用操作,产率的返回值的呼叫的第一个参数在严格的 弱排序关系之前的第二个比较类型,否则为假 。

您的比较函数不符合严格的周订购标准。

你可以简单地做:

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)做同样的事情,因为运算符重载不适用于指针类型。你唯一的选择是通过比较器。

+0

谢谢。我在最后更新了我的帖子和另一个类似的问题。是否正确的方式来覆盖'Person'的布尔运算符<(const Person *)const {}',以便它可以支持对'Person *'的向量进行排序? –

+0

@shijiexu编辑我的回答 – bashrc

+0

谢谢。关于“运算符重载不适用于指针类型”,你的意思是这只是指'operator <(const Person *)'。在测试中,'Person'中的operator <(const Person *)不起作用,但是我发现'PrintPerson'内的operator()(const Person *)'起作用,因为它可以打印出所有元素在'vector ' –

相关问题