なぜstd :: sort()はソートされたベクトルを変更するのですか?

ここに問題があります:

私の最初のクラスでは、私はベクトル、二重変数を持って、私は比較演算子をオーバーロードします。関連するコードは次のとおりです。

class City
{
    double distance;
    std::vector coordinates;

    bool operator<(const City& city) const
    {   
        return this->distance < city.distance;
    } 

   //same for the greater-than operator but changing "<" to ">"
};

別のクラスでは都市のベクトルがあり、条件が満たされるたびに並べ替える必要があります。そのために、私は以下のように定義された構造体を持っています:

編集:(値の代わりに参照)

struct CitySortHelper {
    bool operator() (const City &x, const City &y) const { return x < y; } 
} city_sort;

今、問題の部分は、私はベクトルを並べ替える新しいCityオブジェクトが表示され、私は理由を説明することはできません:

編集:

// this prints all current objects in the vector
for (int i = 0; i < totalCities; i++) {
    std::cout << cities->at(i) << std::endl;
}

// after the following line I get new City objects in the 
// vector, that weren't there before the sort. The new objects
// always have distance = 0 and random values in the coordinates
std::sort(cities->begin(), cities->end(), city_sort);

// using the sort with no predicate also gives the same faulty results
std::sort(cities->begin(), cities->end());

編集: (the copy constructor and assignment operator)

City(const City &city)
{
    this->distance = city.distance;
    this->coordinates = city.coordinates;
}

City& operator= (const City &city)
{
    this->distance = city.distance;
    this->coordinates = city.coordinates;

    return *this;
}

The weird part is that this only happens if I sort the City objects in ascending order, i.e. if I change the comparator operator in the CitySortHelper from "<" to ">" everything works fine.

このようなことが起こる理由は何ですか?どんな助けもありがとうございます。

2
std :: sort(cities-> begin()、cities-> end())、および std :: sort(cities)を使用することができれば、なぜカスタム述語が必要なのでしょうか? - > begin()、cities-> end()、std :: greater
追加された 著者 Kerrek SB,
Cityクラスのコピーコンストラクタがありますか?
追加された 著者 Benjamin Lindley,
私はあなたの問題を再現できません。問題を示す完全でコンパイル可能な例を提供する必要があります。
追加された 著者 Benjamin Lindley,
あなたはstd :: greaterを使うことができると言っていますが、City :: operator>()は表示されません。すべてのSTLは、std :: greater()だけをoperator>に転送しています(つまり、gccであり、それです)。 City :: operator>を定義していれば、それを投稿すると便利かもしれません。
追加された 著者 gred,
また、メンバ関数ではなく、City :: operator <()をフレンド演算子<(const City&a、const City&b)にしてみてください。私は答えとして投稿しなかったのです。
追加された 著者 gred,
@ KerrekSB私も述語なしで試しました。通常の場合、less演算子が使用される場所の std :: sort(cities-> begin()、cities-> end())では、それらの新しいオブジェクトを取得します。 std :: greater を使っても問題はありません。
追加された 著者 iska,

3 答え

CitySortHelper needs to take parameters by const reference, not by value. Another thing to keep in mind is that sort uses assignment operator for the City; check that your assignment operator is working correctly. Taking care of these two issues should fix the problem.

4
追加された
@iskaあなたが行った変更を反映するために質問を更新できますか?
追加された 著者 dasblinkenlight,
@iska totalCities cities-> size()と同じですか?私はあなたのコードをCPPファイルにコピーし、昇順でOKをソートしました。
追加された 著者 dasblinkenlight,
@ codea City <<演算子を投稿できますか?それが私が変更したもう一つのものです(こちらを参照してください)。
追加された 著者 dasblinkenlight,
@iskaそれはOKです、あなたはする必要はありません:)楽しいコーディングをして、この問題を把握して幸運。
追加された 著者 dasblinkenlight,
私は CitySortHelper を変更し、代入演算子とコピーコンストラクタをチェックしました。問題は解決しません。降順では動作しますが、昇順では失敗します。
追加された 著者 iska,
どうぞ。今すぐ私は降順で注文してから、ベクトルを逆にします。
追加された 著者 iska,
はい、実際には私がここで質問する前にチェックした最初のものの中にあったのです。
追加された 著者 iska,
助けてくれてありがとう。私はちょうど今はあきらめて寝ます。明日はもう一度行くだろう。私はすべての時間あなたの答えを投票するつもりです私はあなたを要した:)
追加された 著者 iska,

ソートヘルパーを変更してください

bool operator() ( const City& x , const City& y) const

また、Cityのコピーコンストラクタと代入演算子が適切な処理を行っていることを確認する

1
追加された
私は CitySortHelper を変更し、代入演算子とコピーコンストラクタをチェックしました。問題は解決しません。降順では動作しますが、昇順では失敗します。
追加された 著者 iska,

順序を保持するには std :: sort()を使用しないでください。 std :: stable_sort()を使用してください。 stable_sort 要素が相対順序を維持することを保証します。 sort はそうではありません。

また、 sort はあなたの問題ではないようです。 Cityオブジェクトがベクターのどこかにプッシュされているようですが、ベクトルのイテレータではなくサイズの変数をチェックしているため、気づいていません。このように印刷して、何が出てくるか教えてください:

for (std::vector  ::iterator it = cities->begin(); it != cities->end(); ++it) {
    std::cout << *it << std::endl;
}
0
追加された