我在以下代码中创建了一个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
我在buntu中使用gcc 4.6.3
。
答案 0 :(得分:6)
关于关联容器要求的C ++ 11标准第23.2.4 / 3段:
短语“等价键”是指比较所强加的等价关系,而不是 密钥上的
operator==
。也就是说,如果进行比较,则认为两个键k1
和k2
是等效的 对象comp
,comp(k1, k2) == false && comp(k2, k1) == false
。 对于任意两个键k1
和k2
同一个容器,调用comp(k1, k2)
应始终返回相同的值。
由于您没有通过更改权重来满足此前提条件(并且比较器使用这些权重来定义集合元素的排序),因此您的程序具有未定义行为。
答案 1 :(得分:1)
作为Andy Prowl引用的必然结果,每次更改体重数组时都需要重新生成一组