【问题标题】:Overloading comparison operators to work with STL sort in C++重载比较运算符以在 C++ 中使用 STL 排序
【发布时间】:2012-03-09 08:16:01
【问题描述】:

我正在编写一个程序,它将读取带有社会安全号码(当然不是真实号码)的姓名列表,并根据命令行参数根据姓氏或 ssn 对列表进行排序。为了简单起见,我重载了

#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;

}

【问题讨论】:

  • 第一个问题:在你想要==的地方使用=。你的编译器没有给你一个讨厌的警告吗?
  • 一般来说,列出您正在使用的编译器以及您收到的确切错误消息会很有帮助。
  • 了解 const 正确性。您的大多数参数都不需要引用非常量
  • 您应该开始在代码中多使用const...比较和插入运算符 (operator&gt;&gt;) 应该通过常量引用获取 record 参数(它们不应更改他们收到的对象)。

标签: c++ sorting stl operator-overloading stl-algorithm


【解决方案1】:

这有点奇怪,你的编译器应该警告一下

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

【讨论】:

  • 哇,我不敢相信我错过了。我解决了这个问题,我还注意到我试图输出一个向量而不是一个记录。但是,当我尝试使用排序算法时,我仍然遇到错误。我想我要么错误地调用了该函数,要么我的 operator
【解决方案2】:

您确定为您的record 类进行排序具有真正的意义,而不仅仅是用于任意排序目的?考虑一个用于大整数的类,其中对您的对象进行这样的排序是有意义的,但它对您的记录是否有意义?或者,如果你从不排序,它会失去意义吗?

[imo] 不要将operator&lt; 引入的这个排序与你的类定​​义结合起来,除非它与它有真正的对应关系,换句话说,如果人类直观地清楚某个“对象 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());
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 1970-01-01
    • 2011-08-12
    • 2023-04-05
    • 2013-06-26
    • 2014-05-07
    相关资源
    最近更新 更多