条款22:避免原地修改set和multiset的键
2007-05-13 00:05
274 查看
因为set或multiset里的值不是const,所以试图改变它们可以编译。本条款的目的是提醒你如果你改变set或multiset里的元素, 你必须确保不改变一个键部分——影响容器有序性的元素部分。如果你做了,你会破坏容器,再使用那个容器将产生未定义的结果, 而且那是你的错误。另一方面,这个限制只应用于被包含对象的键部分。对被包含元素的所有其他部分来说,是开放的:随便改变!
即使set和multiset的元素不是const,实现仍然有很多方式可以阻止它们被修改。例如,实现可以让用于set<T>::iterator的operator*返回一个常数T&。即,它可以让set的迭代器解引用的结果是set元素的常量引用。在这样的实现下,将没有办法修改set或multiset的元素,因为所有访问那些元素的方法都将在让你访问之前加一个const。
这样的实现合法吗?可以证明是。也可以证明不是。标准在这里有矛盾,而根据Murphy定律(译注:Murphy定律就是“If there are two or more ways to do something, and one of those ways can result in a catastrophe, then someone will do it.”(当有两条或更多的路让你抉择,如果其中一条会导致失败,那么你一定会选到它。)随着时间流逝,这一“定律”逐渐进入习语范畴,其内涵被赋予无穷的创意,也出现了众多的变体,其中最著名的一条也被称为Finagle定律,具体内容为:“If anything can go wrong, it will.”(如果一个东西可能会出错,那它一定会出错。)这一定律被认为是对“Murphy定律”最好的模仿和阐述。),不同实现会以不同的方式解释它们。结果是发现这些代码,我早先声明可以编译的,却经常在某些STL实现上不能编译: 如果不关心移植性,你想要改变set或multiset中元素的值,而且你的STL实现让你侥幸成功,继续做。只是要确定不要改变元素的键部分,即,会影响容器有序性的元素部分。如果你在乎移植性,就认为set和multiset中的元素不能被修改,至少不能在没有映射的情况下。
即使set和multiset的元素不是const,实现仍然有很多方式可以阻止它们被修改。例如,实现可以让用于set<T>::iterator的operator*返回一个常数T&。即,它可以让set的迭代器解引用的结果是set元素的常量引用。在这样的实现下,将没有办法修改set或multiset的元素,因为所有访问那些元素的方法都将在让你访问之前加一个const。
这样的实现合法吗?可以证明是。也可以证明不是。标准在这里有矛盾,而根据Murphy定律(译注:Murphy定律就是“If there are two or more ways to do something, and one of those ways can result in a catastrophe, then someone will do it.”(当有两条或更多的路让你抉择,如果其中一条会导致失败,那么你一定会选到它。)随着时间流逝,这一“定律”逐渐进入习语范畴,其内涵被赋予无穷的创意,也出现了众多的变体,其中最著名的一条也被称为Finagle定律,具体内容为:“If anything can go wrong, it will.”(如果一个东西可能会出错,那它一定会出错。)这一定律被认为是对“Murphy定律”最好的模仿和阐述。),不同实现会以不同的方式解释它们。结果是发现这些代码,我早先声明可以编译的,却经常在某些STL实现上不能编译: 如果不关心移植性,你想要改变set或multiset中元素的值,而且你的STL实现让你侥幸成功,继续做。只是要确定不要改变元素的键部分,即,会影响容器有序性的元素部分。如果你在乎移植性,就认为set和multiset中的元素不能被修改,至少不能在没有映射的情况下。
相关文章推荐
- effective STL - 避免原地修改set和multiset的键
- 避免原地修改set和multiset的键而修改其值
- Effective STL 22 Avoid in-place key modification in set and multiset
- Mybatis 实现不确定修改几个字段的修改方法(动态语句set、if实现),避免修改时其它没被修改的字段变为null
- effective stl 第22条:切勿直接修改set和multiset中的键
- android 只修改ViewPager调用setCurrentItem时,滑屏的速度,其他正常
- 用vi修改文件,保存文件时,提示“readonly option is set”的解决方法。
- MySql修改数据库编码为UTF8避免造成乱码问题
- std::find ,set.find, multiset.find, map.find和multimap.find算法总结
- Oracle数据库需要修改默认的Profiles,避免用户密码过期
- map/multimap/unordered_map/unordered_multimap; set/multiset/unordered_set/unordered_multiset
- 修改jquery.alerts, 避免闪一下
- 条款20: 避免public接口出现数据成员
- STL中的set和multiset学习小记
- 避免 Hibernate 中用get/load方法获取的实体调用set方法后自动更新
- c++在用set和multiset时遇到的一个bug
- 【Linux】解决用vi修改文件,保存文件时,提示“readonly option is set”
- 条款22:将成员变量声明为private
- (关联容器)set 和 multiset
- std::set的迭代器不能修改对应的元素