Why isn't my overloading < operator not wor

2019-09-01 06:54发布

问题:

I have this following code where I want to sort vector of string according to the last character of the string. I've done the following but the sorting is done by default rules.

Here's the overloading < part:

bool operator<(const string &s1, const string &s2){
    return s1.at(s1.size() - 1) < s2.at(s2.size() - 1);
}

This is in main:

vector <string> nameList;
int n;
cin>>n;
while(n--){
    string name;
    char str[100];
    cin>>str;
    name += str;
    nameList.push_back(name);
}

sort(nameList.begin(), nameList.end());
for(int i = 0; i < nameList.size(); i++)
    cout<<nameList.at(i)<<endl;

Code in ideone: LINK

回答1:

As noted, your operator< is not being called, std::string already has overloaded operators in the std namespace.

There are two versions of std::sort, one that will use operator< and another that takes a custom predicate to sort the container. Add a custom predicate, you can still used sort to sort your vector as required;

#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
using namespace std;

bool lastchar(const string &s1, const string &s2){
    return s1.at(s1.size() - 1) < s2.at(s2.size() - 1);
}

int main(){
        vector <string> nameList;
        int n;
        cin>>n;
        while(n--){
            string name;
            char str[100];
            cin>>str;
            name += str;
            nameList.push_back(name);
        }

        sort(nameList.begin(), nameList.end(), &lastchar);
        for(int i = 0; i < nameList.size(); i++)
            cout<<endl<<nameList.at(i);

        return 0;
}

I've called it lastchar, but you can name it what ever is best. As an added bonus, if you can used C++11 or above, you can make the predicate a lambda.

sort(nameList.begin(), nameList.end(), [] (const string &s1, const string &s2){
  return s1.at(s1.size() - 1) < s2.at(s2.size() - 1);
});


回答2:

It's not being used, you have to pass it into std::sort - something like:

sort(nameList.begin(), nameList.end(), [](const string &s1, const string &s2) {
    return s1.at(s1.size() - 1) < s2.at(s2.size() - 1);
}