博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Effective_STL 学习笔记(二十二) 避免原地修改 set 和 multiset 的健
阅读量:7165 次
发布时间:2019-06-29

本文共 1148 字,大约阅读时间需要 3 分钟。

 

正如所有标准关联容器,set 和 multiset 保持它们的元素有序,容器的正确行为依赖于它们保持有序,如果改变一个元素的值,新值不在正确的位置,将破坏容器的有序性。

 

对于 map 和 multimap 容器,改变容器里一个键值的程序不能编译,

map<K, V> 或 multimap<K, V> 类型的对象中的元素类型是 pair<const K, V>,

键的类型是 const K 不能改变。  

 

而对于 set 和 multiset 为 set<T> 和 multiset<T>,非 const 的原因:

想要元素 T 中,非元素的键的部分可以被修改

1. 如果不关心移植性,想要改变 set 或 multiset 中元素的值,只要确定不要改变元素的键的部分

2. 如果在乎移植性,就认为 set 和 mutiset 中的元素不能被修改,至少不能在没有映射的情况下。

映射掉引用:

1   if( i != se.end() )2   {3     const_cast
(*i).setTitle("Corporate Deity"); //映射掉 *i 的常量性4   }

告诉编译器把映射的结果当作一个(非常数)Employee 的引用,然后在引用上调用setTitle

 

如果总可以工作而且总是安全的改变 set、multiset、map 或 multimap 里的元素,通常按五个步骤去做:

1. 定位你想要改变的容器元素

2. 拷贝一份要修改的元素

3. 修改副本

4. 从容器里删除元素,通常通过调用 erase

5. 把新值插入容器

以安全可移植的方式写:

1   EmpIDSet se; 2   Employee selectedID; 3   . . . 4   EmpIDSet::iterator i = se.find( selectedID );  // 第一步:找到要改变的元素 5   if( *i != se.end() ) 6   { 7     Employee e(*i);   // 第二步:拷贝这个元素 8     se.erase( i++ );  // 第三步:删除这个元素,自增这个迭代器以保持它有效 9     e.setTitle( "Corporate Deity" );  // 第四步:修改这个副本10     se.insert(i, e);             // 第五步:插入新值,位置和原来位置一样11   }

 

总的来说,避免原地修改 set 和 multiset 的键

 

转载于:https://www.cnblogs.com/kidycharon/p/10028538.html

你可能感兴趣的文章