2016-05-13 11 views
0

パラメータに応じてリストのstd :: listをソートしたいと思います。例:std :: listの並べ替え<myclass*> myclass :: operator [](int i)

class myclass 
{ 
    string name, surname; 
public: 
    myclass() {} 
    ~myclass() {} 
    string operator[](int i) 
    { 
     switch (i) 
     { 
     case 1: return name; 
     case 2: return surname; 
     } 
    } 
}; 

template <typename T> 
struct compare 
{ 
    int num; 
    indirect_compare() {} 
    indirect_compare(int i) : num(i) {} 
    ~indirect_compare() {} 
    bool operator()(T * lhs, T * rhs) { return (*lhs)[num] < (*rhs)[num]; } 
}; 

list<myclass*> lst; 
int specified_by_user; 
cin >> specified_by_user; 

//later 

lst.sort(compare<myclass>(specified_by_user)); 

これは問題なく動作しますが、正しいかどうかはわかりません。構造体のコンストラクタとデストラクタでメッセージを追加したとき、コンストラクタは一度しか呼び出されませんでしたが、デストラクタはたとえば9回呼び出されていました。なぜ起こったのかわかりません。私はそれを確認するためにこのプログラムをデバッグしようとしたが、私は理由を見つけることができませんでした。

ありがとうございました!

+2

他のコンストラクタは、おそらくコピーctorのでした。あなたはそれを監視しましたか? – Sheph

+0

比較のctorとdtorの名前はindirect_compareです。この例はコンパイルされていますか?また、使用するのが無効な場合は、引数なしのctorを取り除いてください。 – Sheph

+0

「正しいかどうかわからない」と思っていますが、いくつかの方法がありますが、違いはありません – vu1p3n0x

答えて

1

私は演算子[]から比較関数オブジェクトにスイッチを移動しようとします(代わりにラムダを使用することもできます)。これにより、同じタイプではないプロパティを比較することができます。 (例えば、あなたがメンバーを追加した場合など)int age;

また、ポインタのリストではなく、1つのコンストラクタと複数の削除問題が発生する可能性があります。 。

このような何か:

struct myclass 
{ 
    string name; 
    string surname; 
}; 

template <typename T> 
struct compare 
{ 
    int num; 
    compare() {} 
    compare(int i) : num(i) {} 
    ~compare() {} 
    bool operator()(const T & lhs, const T & rhs) { 
    switch(num) 
    { 
     case 1: return lhs->name < rhs->name; 
     case 2: return lhs->surname < rhs->surname; 
     default: throw std::logic_error(); 
    } 
    } 
}; 

list<myclass> lst; 
+0

お返事ありがとうございます!アイデアは申し分ないですが、私はメンバーの名前と姓をプライベートに保ちたいと思っています。クラスにもっと多くの文字列があるので、メンバーごとにゲッターとセッターを作成したくありません。だから、私は演算子[]を使ったのです。 – Ben

0

あなたのコードは正常に見えるあなたの解決策は少し珍しいですが、あなたはそれのために行くためにミルチアバハの精神で、それが動作するかどうか、私が表示したいです!インスピレーションのために、あなたの問題に対する別の解決方法をお試しください:

if (specified_by_user) // sort by name 
    lst.sort(auto [](auto const & a, auto const & b){ return a.name < b.name; }); 
else // sort by surname 
    lst.sort(auto [](auto const & a, auto const & b){ return a.surname < b.surname; }); 

最初に、どのフィールドをクラスからソートしてクライアントコードに移すかを決定します。次に、コンパイラ構造体を定義する代わりにlambdaをlst.sort()に渡します。lambdaは関数呼び出し自体のインラインで非常に簡潔に定義できます。

これは、フィールド名と姓が公開されていることを意味します(ラムダがアクセスできるようになります)。あなたがプライベートそれらを維持したい場合は、代わりに自分のクラスにゲッターを追加することができます。

string const & get_name() const { return name; } 

と少しラムダを変更:

auto [](auto const & a, auto const & b){ return a.get_name() < b.get_name(); } 
+0

素晴らしいですが、私はメンバーの名前と姓をプライベートに保ちたいと思います。私のクラスにもっと多くの文字列があるので、各メンバーのgetterとsetterを作成したくありません(特にこの場合のみ使用します)。比較は同じように動作するので、コードを短くしようとしました。それが私が演算子[]を使用した理由です。 – Ben

関連する問題