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.3在buntu中使用。

4

2 回答 2

6

根据 C++11 标准关于关联容器要求的第 23.2.4/3 段:

短语“键的等价”是指通过比较而不是 operator==on 键强加的等价关系。也就是说,如果对于比较对象, ,则两个键k1k2被认为是等效的。对于同一容器中的任意两个键,调用应始终返回相同的值compcomp(k1, k2) == false && comp(k2, k1) == falsek1k2comp(k1, k2)

由于您没有通过更改权重来满足此先决条件(并且您的比较器使用这些权重来定义集合元素的排序),因此您的程序具有Undefined Behavior

于 2013-04-08T13:25:47.347 回答
1

作为 Andy Prowl 引用的推论,每次更改权重数组时都需要重新生成一个新集合

于 2013-04-08T13:27:28.617 回答