STL 陷阱或缺陷

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值