簡體   English   中英

重載比較運算符以在C ++中使用STL排序

[英]Overloading comparison operators to work with STL sort in C++

我正在編寫一個程序,該程序將讀取具有社會安全號碼的名稱列表(當然不是真實的名稱),並根據命令行參數根據姓氏或ssn對列表進行排序。 為了簡單起見,我已經重載了<運算符和重載了輸入和輸出運算符。 一切都可以正常編譯,直到我在main末尾添加sort函數和輸出為止。 我很沮喪 有任何想法嗎? 任何其他提示也將不勝感激。

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

測試booltruefalse是有點不必要反正這是什么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());
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM