2017-11-07 8 views
2

複数のパラメータで定義されたオブジェクトStudentiのリストがあります。 私はこのリストを並べ替えたい、最初は平均して、平均が同じならアルファベット順にソートします。私のクラスの学生で複数のパラメータによるSTLソートC++

私はこのヘッダ関数宣言: bool mediaDescrescator(const&, const&); この方法で実装されています

bool Studenti::mediaDescrescator(const Studenti& a, const Studenti& b) 
{ 
    if(a.medie_ != b.medie_) 
    { 
     return (a.medie_ > b.medie_); 
    } 

    return (a.nume_ > b.nume_); 
} 

medie_はStudenti nume_のダブルプライベートメンバであるのはstd ::文字列のプライベートメンバーですメインでStudenti

私はStudentiのリストを持っている: std::list<Studenti> listaStud_ = {stud1, stud2, stud3, stud4, stud5};

関数呼び出し: std::sort(listaStud_.begin(), listaStud_.end(), mediaDescrescator);

エラー:mediaDescrescatorがこのスコープで宣言されていません。

私はこのタイプのソートに関する他のトピックを見てきました。それらは私のように宣言されています。リストの代わりにベクトルタイプを使ってみました。 mediaDescrescatorは、関数ポインタまたは関数オブジェクトとして渡す必要があるため、without()と呼ばれます。

答えて

5

mediaDescrescatorは、Studentiのメンバ関数です。クラスのレキシカルスコープで定義されています。したがってStudenti::mediaDescrescatorにアクセスできますが、mediaDescrescatorにはアクセスできません。グローバル名前空間にはmediaDescrescatorという名前の関数はありません。

また、次のエラーを回避するには、staticメンバ関数であることを確認してください。結局のところ、それを呼び出すための有効なインスタンスは必要ありません。 thisのメンバー変数にはアクセスしません。

+0

解決策演算子を忘れました...ありがとうございます。 –

1

変更関数宣言:

bool mediaDescrescator(const Studenti& a, const Studenti& b) 

は、基本的には、クラスの外にそれを持っています。

メンバをパブリックにしたくない場合は、それらのゲッタ関数を記述し、ソートの代わりに使用します。

+0

getとsetを指定しても、クラスオブジェクトの処理を行うために、クラスの外で関数を定義することは良い習慣です。 –

+1

ソート機能を1回しか使用しない場合は、その場所にラムダ関数を書くことをお勧めします。ベストプラクティスは可能な限りクラスに含まれている自己を持つことですが、時にはそれは時間の価値がありません。 –

5
  1. std::tieは、参考文献のstd::tupleを返します。

  2. std::tupleは、正しい辞書編集比較を実行する比較演算子を定義します。

だから、すべてを行う必要があるtietupleStudentiを回している - そして、タプルを比較します。

bool Studenti::mediaDescrescator(const Studenti& a, const Studenti& b) 
{ 
    return std::tie(a.medie_, a.nume_) > std::tie(b.medie_, b.nume_); 
} 

あなたはそれが役に立つあなたが書いたクラスでas_tuple()と呼ばれる方法を提供するかもしれません:あなたの実装にはいくつかの問題があります

struct Studenti 
{ 
    // rest of class 

    auto as_tuple() const { return std::tie(medie_, nume_); } 
}; 
2

。最初に、コンパイラが文句を言うのは、mediaDescrescatorStudentiのスコープで定義されていて、グローバルスコープでそれにアクセスしようとすると、Studenti::mediaDescrescatorを使用してポインタを取得します。次に、mediaDescrescatorは、通常のメンバ関数のStudentiであり、オブジェクトに対して呼び出す必要があります。これは固定することができます。その代わりに静的メンバ関数にするか、または1つのパラメータをとり、現在のオブジェクトと比較することによって実現できます。第3に、std::sort関数はランダムアクセスイテレータを必要とするためstd::listには適用できません。std::listは双方向イテレータのみを提供します。

+0

あなたはどこにリストがあるのですか?私は他のトピックでこれを見てきました。しかし、リスト型を使用する必要があります。ベクター型でコピーを作成せずに、このタイプの並べ替えを適用するにはどうすればよいですか? –

+1

https://stackoverflow.com/a/2432946/104774は 'std :: list <> :: sort()'を使っていると言っています – stefaanv

1

最初に、mediaDescrescator()が非スタティックメンバ関数である場合、thisメンバを動作させることができるため、1つの "other"パラメータのみが必要です。

第二に、ラムダは、アルゴリズムはメンバ関数(テストしていません)で動作していするのは簡単です:

listaStud_.sort([](const studenti& a, const studenti& b) { return a.mediaDescrescator(b); }); 

リチャード・ホッジス答えを組み合わせてあなたは、この場合にも(ラムダに直接注文機能を実装することができヨハンの答えに基づいて

listaStud_.sort([](const studenti& a, const studenti& b) { return std::tie(a.medie_, a.nume_) > std::tie(b.medie_, b.nume_); }); 

::)公共のメンバーとstd::sortstd::list上で使用することはできません、私のコードスニペットのように代わりにstd::list<>::sort()を使用しています。

関連する問題