6.6 Map
在Map中移除元素时,当心发生意外状况。当你移除迭代器所指对象时,有一个很大的危险,看看这个例子:
typedef map<stirng, int> sim;
sim coll;
sim::iterator pos;
.......
for(pos = coll.begin(); pos != coll.end(); ++pos) {
if(pos->second == value) {
coll.erase(pos); //Runtime error!!!!!!!!
}
}
对pos实施一个erase()函数,会使pos成为一个无效的迭代器,此后如果你没有对pos重新赋值就使用pos,会出现未有定义错误,其实只需要++pos就可以。
正确做法为:
....................
for(pos = coll.begin(); pos != coll.end(); ) {
if(pos->second == value) {
coll.erase(pos++);
}
else {
++pos;
}
}
注意pos++会将pos移到下一个元素,但返回其原始值的一个副本,当调用erase()时,pos已经不再指向那个即将被删除的元素了。
7.2.6 Vector迭代器的递增和递减
迭代器的递增和递减操作有个奇怪的问题。一般而言你可以递增或递减暂时性迭代器。但对于vectors和string就不行。例如;
Vector<int> coll;
……………
Sort(++coll.begin(), coll.end());//这样会出错,换成别的容器就没错
因为,vector的迭代器通常被实作为一般指针。C++不允许你修改任何基本类型(包括指针)的暂时值,但对于struct和class则允许。可改为:
Vector<int> coll;
………
If(coll.size() > 1) {
Vector<int>::iterator beg = coll.begin();
Sort(++beg, coll.end()); //这样一来就不会出错了
}
第8章 STL仿函数
仿函数是passed by value(传值),不是passed by reference(传址),因此算法并不会改变随参数而来的仿函数的状态。将仿函数以by value方式传递的好处是,你可传递常量或暂时表达式。如果不这么设计,你就不可能传递IntSequence(1)这样的表达式。缺点是,你无法改变仿函数的最终状态。如:
generate_n(back_inserter(il), 9, addValInsert(1));
generate_n(back_inserter(il), 9, addValInsert(1));
你在程序中用两次这个,其实只是用了一次,因为你只不过改变的是仿函数的副本而已,你无法改变其最终状态。
有两个办法可以从“运用了仿函数”的算法中获取“结果”或“反馈”:
(1) 以by reference的方式传递仿函数。
(2) 运用for_each()算法的回返值。
第9章 STL算法
1. 变动性算法、变序性算法和移除性算法都不能把关联式容器当成目标区间。主要原因是关联式容器的元素被视为常数,不能更改。也不可做为排序算法的目标区间。
2. Search的二元判断式形式中的两个参数分别是第一个区间和第二个区间的。
9.7 remove和unique都是逻辑上的删除,“原本位置在后的”未删除的元素向前移,覆盖被移除的元素。调用者在调用这些算法之后,应该保证从此使用返回的新逻辑终点,而不使用原先的.end()
10.4 你不可以改变bitsets中位的数量,这个数量的具体值是由template参数决定的。如果你需要一个可变长度的位容器,可考虑使用vector<bool>。
第11章 String
1. C_String 是指char* 或const char*, 在结尾有个’/0’,而String对象的字符串后面没有。
2. 在find()方法中,如果搜寻失败返回一个特殊的值string::npos,定义于string class中。所有搜寻函数的返回类型都是string::size_type,它是定义于string class中的一个无正负号的整数类型,只有这个类型能与sting::npos运行比较动作。
3. 一般而言,整个程序中你应该坚持使用strings,直到你必须将其内容转化为char*时才把它们转换为C_string。请注意c_str()和data()的返回值有效期限在下一次调用non-const成员函数时即告终止。例如:
Stirng s;
Const Char* p;
Fum(c_str()); //Fum函数接受c_str参数
P = s.c_str();
Fum(p);
S += “ext”; //从此开始变的无效
Fum(p); //error