2

私は、社会保障番号(もちろん実際の番号ではありません)を持つ名前のリストを読み取り、コマンドラインの引数に応じて、姓または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;

}
4

2 に答える 2

5

これはちょっと奇妙で、コンパイラが警告すべきことです

if (rhs.t_sort = false)

の値をテストしていませんがt_sort、常にfalseに設定しています。

-ステートメントがすでに実行していることであるため、またはboolに対してテストする必要はありません。truefalseif

代わりにこのコードを試してください

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;
    }
}
于 2012-02-18T07:05:33.990 に答える
1

recordクラスの順序を設定することは、任意の並べ替えの目的だけでなく、本当の意味を持っていると確信していますか?オブジェクトのそのような順序付けが理にかなっている大きな整数のクラスを考えてみてください。しかし、それはあなたのレコードにとってそのような有効な意味がありますか?それとも、ソートしないと意味が失われますか?

[imo]operator<それが実際に対応していない限り、つまり、ある「オブジェクトa」がある「オブジェクトb」よりも小さいことが人間にとって直感的に明らかである場合を除いて、クラス定義によって導入されたこの順序を組み合わせないでください。

これは、直感的に順序付けできないクラスオブジェクトの順序を変えたい場合に特に当てはまります。昇順と降順、名前、名前、車の数などを考えてみてください。そうすると、ドキュメント/コードを調べないと、デフォルトの順序が何であるかを誰も覚えていないため、利便性さえ失われます。

代わりに、ファンクターまたはインプレースラムダ関数を渡します。

#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());
}
于 2012-02-21T15:47:18.767 に答える