如果集合中元素的值发生更改,则排序可能不再正确。正如这个小程序所示:
#include <algorithm>
#include <iostream>
#include <set>
#include <string>
struct Comp
{
bool operator()(const std::string * lhs, const std::string * rhs)
{
return *lhs < *rhs;
}
};
int main()
{
typedef std::set<std::string*, Comp> MySet;
MySet mySet;
std::string * a = new std::string("a");
mySet.insert(a);
std::string * c = new std::string("c");
mySet.insert(c);
std::string * b = new std::string("b");
mySet.insert(b);
for (MySet::iterator it = mySet.begin(); it != mySet.end(); ++it)
{
std::cout << *(*it) << std::endl;
}
// Ouput has correct order:
// a
// b
// c
*b = "z";
std::cout << std::endl;
std::string * d = new std::string("d");
mySet.insert(d);
for (MySet::iterator it = mySet.begin(); it != mySet.end(); ++it)
{
std::cout << *(*it) << std::endl;
}
// Output no longer ordered correctly:
// a
// d
// z
// c
return 0;
}
如何判断设备“刷新”其内部排序?
答案 0 :(得分:9)
这里非常相似的主题(虽然不是很重复,因为你通过自定义比较存储指向可变对象的指针):
what happens when you modify an element of an std::set?
基本上,不要做你想做的事。相反,当您想要修改set
持有指针的对象时,首先删除指针,然后修改对象,然后重新插入指针。
答案 1 :(得分:5)
简单地说,你不能。如果将项目放入集合中,则不应以更改其顺序的方式更改项目。如果需要以这种方式更改项目,则需要将其从set(set :: erase)中删除,然后使用新值重新插入新项目(std :: insert)。
答案 2 :(得分:2)
如果集合中元素的值发生变化
停止!这不合法。
std::set
没有提供任何方法来做你所要求的事情,因为它已经是一个先决条件,永远不需要手动重新订购。
答案 3 :(得分:1)
值得指出的是,如果您使用vs 2008,std::set
实现支持非const迭代器,使您描述的代码使用该库成功编译。在其他stl实现中(例如sgi's),set::const_iterator
和set::iterator
属于同一类型,会抱怨显式设置新的键值。
答案 4 :(得分:0)
使用不同的比较谓词将其复制到自身。
std::set MySet();
/* add entries*/
MySet = std::set(MySet.begin(), MySet.end(), Comp);
通常这用于指定不同的比较操作,例如使用存储的类/结构的不同部分对其进行排序。