• Effective_STL 学习笔记(二十二) 避免原地修改 set 和 multiset 的健


    正如所有标准关联容器,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<Employee &> (*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 的键

  • 相关阅读:
    windows 下安装securecrt 绿色版
    对Linux命令进一步学习vim(二)
    提高php编程效率的小结
    javaScript 的小技巧
    常用 Git 命令文档和命令
    你 get 了无数技能,为什么一事无成
    Ubuntu14.4下安装FTP
    对Linux命令进一步学习
    可以输入也可以下拉选择的select
    APP接口基础学习一
  • 原文地址:https://www.cnblogs.com/kidycharon/p/10028538.html
Copyright © 2020-2023  润新知