STL set 容易引起误解的一个地方
来源:互联网 发布:java log4j%意思 编辑:程序博客网 时间:2024/05/21 05:18
STL set 容易引起误解的一个地方
#include <set>
#include <string>
#include <iostream>
using namespace std;
using std::set;
using std::string;
struct student {
string name;
int grade;
student(string const&name_, intgrade_)
: name(name_)
, grade(grade_)
{}
bool operator<(student const&rhs) const
{
returnname < rhs.name;
}
bool operator==(student const&rhs) const
{
returnname == rhs.name;
}
};
int main(void)
{
set<student> students;
students.insert(student("Li Lei", 5));
students.insert(student("Han Meimei", 5));
students.insert(student("Jim Green", 5));
for (set<student>::iteratori = students.begin();
students.end() != i;
++i)
{
(i->grade)+=1;
}
return 0;
}
STL set是只读机制,set 的只读制度是非常龌龊的, 简而言之, 只要你敢往这个坑里面放, 你就得接受它们以后再也无法修改的命运
student 类的 key 是 name, 跟 grade 没有关系, 原则上来说, 修改后者并不会破坏 set 的存储结构. 然而, 编译器一棒子打死, 不许改, 除非剩下的成员全部 mutable 修饰.
只读制度悲剧的根源在于, set 所谓的 key 撑死只是个假象, value_type 这玩意儿就是 key_type 本身, 既然名份这个大框框定了, 那再怎么折腾也只是折腾, 二奶再怎么被临幸也是二奶, 总也到不了拿证那一步.
伪 key 导致的不仅仅是不能改, 重要的是还不能查! 看看 set::find 函数的参数, 要的又是阴魂不散的 key_type. 这意味着什么? 意味着 Han MM 同学报出她名字的时候, 还查不出她几年级, 而必须要利用她的名字, 伪造一个充气娃娃放进去才能找到! 看到这里我就败了, 这明摆着就是不让我用 set, 让我转投 map 么? 一个也许可行的方案是
#include<map>
#include<string>
usingstd::map;
usingstd::string;
structstudent_periphery {
intgrade;
};
map<string,student_periphery> students;
Dev-Cpp g++下编译不通过, 但是在aixxlC下通过的代码
可能原因:
set returns const iterators (the standardsays set::iterator is const, and that set::const_iterator and set::iterator mayin fact be the same type - see 23.2.4/6 in n3000.pdf) because it is an orderedcontainer. If it returned a regular iterator, you'd be allowed to change theitems value out from under the container, potentially altering the ordering.没办法,如果想修改的话只能先删除再添加咯。这点stl做的有点傻阿。我改后面那个值与你索引的那个有嘛关系,为啥不可以修改捏?
只应该对索引的那个键进行const保护塞。。。
set一般是用红黑树来实现的,所以结点的值不能修改,因为改了之后会对树造成破坏(不再是排序二叉树),之后对set的任何操作 都可能得到不确定的结果。
如果要修改,你可以erase掉某个结点修改后再重新insert
标准的STL这里肯定是不能改的,所以你的程序会有严重的移植问题
由于set不是一个简单的线性结构,如果能够修改,就不能防止人为地修改键值,而这会造成set的崩溃。
在我的VS2008中这段代码也可以很好的运行,可能在VS2008中有这样的机制吧
Reference:
http://www.taoyard.net.cn/?p=79
http://super-jiju.spaces.live.com/blog/cns!806C498DDEE76B61!787.entry
http://www.lslnet.com/linux/dosc1/26/linux-219500.htm
- STL set 容易引起误解的一个地方
- javascript 容易误解的地方
- Shiro容易误解的地方
- java 中容易误解的地方
- 正则表达式中容易误解的地方
- golang http.Redirect()函数容易误解的地方
- String的一个容易迷惑的地方
- Thread.yield的中文API文档引起的一个误解
- mySql update容易出错的一个地方
- 关于NSOperationQueue,一个容易让初学者误解的问题
- android学习记录(六)FragmentTransaction(回退栈)容易误解的地方
- 容易被误解的inline
- wpf-容易误解的Image
- snprintf容易误解的使用方法
- stl::set 的一个缺陷
- 一起来看看protobuf中容易引起bug的一个细节
- 一起来看看protobuf中容易引起bug的一个细节
- 关于c++ fstream的一个容易使用出错的地方。
- 软件怎么找不到啊
- STL SET
- FZU 1896
- Mysql安装版与免安装版的切换使用
- C# dataTable实用例
- STL set 容易引起误解的一个地方
- Ext JS (1) 之Hello World
- 新人报到
- 建立“对象”的概念
- smartephone开发( windows mobile 5.0 )中操作xml
- c++之类的前置声明
- Asp.Net 上传大文件专题(3)--从请求流中获取数据并保存为文件[下]
- 温度检测与仪表
- Grails中的DataBinding数据绑定