ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ### what ***** 给定两个vector,v1和v2,使v1的内容和v2的后半部分一样的最简单方式是什么?不要为“当v2有偶数个元素时才有 一半”而烦恼,只要做一些合理的东西。 正确答案: ``` v1.assign(v2.begin() + v2.size() / 2, v2.end()); ``` ### how ***** 不用区间成员函数来解决这个条款开头的问题,你就必须写一个显式循环: ``` for (vector::const_iterator ci = v2.begin() + v2.size() / 2; ci != v2.end(); ++ci) v1.push_back(*ci); ``` 条款43详细验证了为什么你应该尽量避免手写显式循环,但你不必读那个条款就能知道写这段代码比写assign的调用要 做多得多的工作。 ` ` 避免循环的一个方法是按照条款43的建议,使用一个算法来代替: ``` v1.clear(); copy(v2.begin() + v2.size() / 2, v2.end(), back_inserter(v1)); ``` 写这些仍然比写assign的调用要做更多的工作。此外,虽然在这段代码中没有表现出循环,在copy中的确存在一个循环 (参见条款43)。结果,效率损失仍然存在。 >几乎所有目标区间是通 过插入迭代器(比如,通过inserter,back\_inserter或front_inserter)指定的copy的使用都可以——应该——通过调用区间 成员函数来代替。 这个copy的调用可以用一个insert的区间版本代替: ``` v1.insert(v1.end(), v2.begin() + v2.size() / 2, v2.end()); ``` ### why ***** 我们已经确定两个尽量使用区间成员函数代替它们的单元素兄弟的理由。 ● 一般来说使用区间成员函数可以输入更少的代码。 ● 区间成员函数会导致代码更清晰更直接了当。 ` ` 当处理标准序列容器时,应用单元素成员函数比完成同样目的 的区间成员函数需要更多地内存分配,更频繁地拷贝对象,而且/或者造成多余操作 使用vector区间insert函数 ``` int data[numValues]; // 假设numValues在 其他地方定义 vector v; ... v.insert(v.begin(), data, data + numValues); // 把data中的int // 插入v前部 ``` 在一个显式循环中使用迭代调用来插入,它可能看起来多多少少像这样: ``` vector::iterator insertLoc(v.begin()); for (int i = 0; i < numValues; ++i) { insertLoc = v.insert(insertLoc, data[i]); ++insertLoc; } ``` 1. 把numValues个元素插入v,每次一个,自然会花费你numValues次调用insert。使用 insert的区间形式,你只要花费一次调用,节省了numValues-1次调用。 2. 无效率地把v中的现有元素移动到它们最终插入后的位置的开销。每次调用insert来增 加一个新元素到v,插入点以上的每个元素都必须向上移动一次来为新元素腾出空间。我们在v的前部插入了numValues个元素,如果v在插入前有n个元素,则一共会发生n*numValues次移动。标准要求区间insert函数直接把现有元素移动到它们最后的位置,也就是,开销是每个元素一次移动。 3. 重复使用单元素插入而不是一个区间插入就必须处理内存分配。就像条款14解释的,当你试图去把一个元素插入内存已经满了的vector时,这个vector会分配具有更多 容量的新内存,从旧内存把它的元素拷贝到新内存,销毁旧内存里的元素,回收旧内存。然后它添加插入的元素