如果修改了set中的键值(即作为排序用的主键的值),就会破坏set容器的有序性。
看如下程序:
#include<iostream>
#include<set>
using namespace std;
class Test
{
public:
int key;
Test(int k):key(k)
{
}
void setkey(int newKey)
{
key=newKey;
}
bool operator<(const Test & t) const
{
return key<t.key;
}
};
int main()
{
set<Test>ts;
for(int i=1;i<10;i++)
{
Test t(10-i);
ts.insert(t);
}
set<Test>::iterator it;
for(it=ts.begin();it!=ts.end();it++)
if(it->key==5)
{
it->key=20;
break;
}
for(it=ts.begin();it!=ts.end();it++)
cout<<it->key<<endl;
}
上述程序中,把键值为5的元素的键值修改成了20. 最后输出结果为1 2 3 4 20 6 7 8 9.即set容器的有序性被破坏了。
另外,看下面的程序
1 #include<iostream>
2 #include<vector>
3 #include<string>
4 #include<cmath>
5 #include<set>
6 using namespace std;
7 class Test
8 {
9 public:
10 int key;
11 Test(int k):key(k)
12 {
13 }
14 void setkey(int newKey)
15 {
16 key=newKey;
17 }
18 bool operator<(const Test & t) const
19 {
20 return key<t.key;
21 }
22 };
23 int main()
24 {
25 set<Test>ts;
26 for(int i=1;i<10;i++)
27 {
28 Test t(10-i);
29 ts.insert(t);
30 }
31 set<Test>::iterator it;
32 for(it=ts.begin();it!=ts.end();it++)
33 if(it->key==5)
34 {
35 ((Test)(*it)).setkey(20);
36 break;
37 }
38 cout<<it->key<<endl;
39 }
在第35行中,先把*it强制转换成了Test类型,然后改变了key的值。但是在第38行的输出中,结果不是20,而是5.这时因为 这种类型转换的结果是一个临时的匿名对象,他是*it的一个拷贝,setkey操作被作用到了这个临时变量上。
解决这个问题,可以把地35句换成 const_cast<Test&>(*it).setkey(20); 或者static_cast<Test&>(*it).setkey(20); 这样输出结果就是20.
注意,const_cast与static_cast的区别。
他们都用于强制类型转换。但是const_cast只能作用于引用或者指针,而static_cast即可作用于引用或者指针,还可作用于对象。所以,const_cast<Test>(*it).setkey(20); 这条语句编译时会出错。而static_cast<Test&>(*it).setkey(20); 可以通过编译,但如果把这句话放在上面程序的第35句,输出的结果仍是5,而不是20.