重载比较运算符以使用C++中的STL排序



我正在编写一个程序,该程序将读取带有社会安全号码的姓名列表(当然不是真实的),并根据命令行参数根据姓氏或ssn对列表进行排序。我已经使<运算符以及过载的输入和输出运算符。一切都编译得很好,直到我在main的末尾添加了排序函数和输出。我被难住了。有什么想法吗?任何其他提示也将不胜感激。

#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdlib>
#include <fstream>
using namespace std;
enum sortVar { NAME, SOCSEC };
class record {
    public:
        friend bool operator<(record& rhs, record& name);
        friend ostream& operator<<(ostream& out, record& toWrite);
        friend istream& operator>>(istream& in, record& toRead);
        bool t_sort;    
    private:
        string firstName, lastName, ssn;
};
bool operator<(record& rhs, record& next)
{
    if (rhs.t_sort = false) {
        if (rhs.lastName == next.lastName)
            return rhs.firstName < next.firstName;
        else
            return rhs.lastName < next.lastName;
    }
    else if (rhs.t_sort = true)
        return rhs.ssn < next.ssn;
}
ostream& operator<<(ostream& out, record& toWrite)
{
    out << toWrite.lastName 
         << " " 
         << toWrite.firstName 
         << "    " 
         << toWrite.ssn;
}
istream& operator>>(istream& in, record& toRead)
{
    in >> toRead.lastName >> toRead.firstName >> toRead.ssn;
}
int main(int argc, char* argv[])
{
    if (argc !=3) {
        cerr << "Incorrect number of arguments.n";
        exit(1);
    }
    if (argv[1] != "name" || argv[1] != "socsec") {
        cerr << "Argument 1 must be either 'name' or 'socsec'.n";
        exit(1);
    }
    sortVar sortMode;
    if (argv[1] == "name")
        sortMode = NAME;
    else if (argv[1] == "socsec")
        sortMode = SOCSEC;
    ifstream fin(argv[2]);
    vector<record> nameList;
    while(!fin.eof()) {
        record r;
        if (sortMode == NAME)
            r.t_sort = false;
        else if (sortMode == SOCSEC)
            r.t_sort = true;
        fin >> r;
        nameList.push_back(r);
    }
    //sort(nameList.begin(), nameList.end());
    //cout << nameList;
}

这有点奇怪,编译器应该警告

if (rhs.t_sort = false)

您没有测试t_sort的值,但总是将其设置为false。

无论如何,针对truefalse测试bool是有点不必要的,因为这是if-语句已经在做的事情。

试试这个代码代替

bool operator<(const record& rhs, const record& next)
{
    if (rhs.t_sort) {
        return rhs.ssn < next.ssn;
    }
    else
    {
        if (rhs.lastName == next.lastName)
            return rhs.firstName < next.firstName;
        else
            return rhs.lastName < next.lastName;
    }
}

您确定为record类排序有真正的意义吗?考虑一个大整数类,其中对象的这种排序是有意义的,但它对记录有意义吗?或者,如果你从不分类,它会失去意义吗?

[imo]不要将operator<引入的这种排序与您的类定义相结合,除非它与它有真正的对应关系,换句话说,如果人类直观地清楚某些"对象a"小于某些"对象b"。

如果您希望对不直观排序的类对象有不同的排序,请考虑升序与降序、按名字、按姓氏、按汽车数量等,这一点尤其正确。如果不查找文档/代码,就没有人会记得默认的排序是什么,从而失去了它的便利性。

相反,要么传递函数,要么就地lambda函数:

#include <algorithm>
#include <functional>
#include <vector>
struct Foo {
    int x;
    Foo (int x) : x(x) {}
};
struct FooAscending : std::binary_function<Foo,Foo, bool>
{
    bool operator() (Foo const &lhs, Foo const &rhs) const { 
        return lhs.x < rhs.x;
    }
};
int main () {
    std::vector<Foo> foos;
    foos.emplace_back(1);
    foos.emplace_back(2);
    sort (foos.begin(), foos.end(), 
          [](Foo const &l, Foo const &r) { return l.x < r.x; });
    sort (foos.begin(), foos.end(), 
          [](Foo const &l, Foo const &r) { return l.x > r.x; });
    sort (foos.begin(), foos.end(), FooAscending());
}

最新更新