1

std::set次のコードで、要素が配列に基づいてソートされたままになるを作成しました。

int weight[] = {0, 1, 58, 21, 10, 21, 24};

struct Comp
{
    public:
    bool operator() (const int &a, const int &b) const
    {
        if (weight[a] == weight[b])
            return a < b;
        else
            return weight[a] < weight[b];
    }
};
set<int, Comp> s;

驚いたことに、weight配列内の要素を変更すると、セット内の対応する要素が消えてしまいます。ここに私のテスト関数があります:

void print()
{
    printf("Elements = ");  
    for(int i = 1; i <= 6; i++)
        if(s.find(i) != s.end())
            printf("%2d ", i);;
    printf("\n");
}

int main()
{   
    for(int i = 1; i <= 6; i++)
        s.insert(i);

    print();
    weight[2] = 1;
    weight[5] = 15;
    print();

    return 0;
}

出力:

Elements =  1  2  3  4  5  6  
Elements =  1  3  4  6

gcc 4.6.3buntuで使用しています。

4

2 に答える 2

6

連想コンテナーの要件に関する C++11 標準のパラグラフ 23.2.4/3:

「キーの等価性」という語句は、キーではなく、比較によって課せられる等価関係を意味 operator==します。つまり、2 つのキーk1k2は、比較対象comp,の場合、同等と見なされますcomp(k1, k2) == false && comp(k2, k1) == false同じコンテナー内の任意の 2 つのキーについてk1k2呼び出しcomp(k1, k2)は常に同じ値を返します

重みを変更することによってこの前提条件を満たしていないため (そして、コンパレーターはこれらの重みを使用してセットの要素の順序を定義します)、プログラムにはUndefined Behaviorがあります。

于 2013-04-08T13:25:47.347 に答える
1

Andy Prowl が引用した結果として、重み配列を変更するたびに新しいセットを再生成する必要があります。

于 2013-04-08T13:27:28.617 に答える