🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ### 自定义插入 ``` int transmogrify(int x); // 这个函数从x // 产生一些新值 vector values; ... // 把数据放入values vector results; // 把transmogrify应用于 transform(values.begin(), values.end(), // values中的每个对象 results.end(), // 把这个返回的values transmogrify); // 附加到results // 这段代码有bug! ``` transform被告知它的目的区间是从results.end()开始的,所以那就是开始写在values的每个元素上调 用transmogrify的结果的地方。就像所有使用目标区间的算法,transform通过对目标区间的元素赋值的方法写 入结果,transform会把transmogrify应用于values\[0\]并把结果赋给\*results.end()。然后它会把transmogrify应用于 value\[1\]并把结果赋给\*(results.end()+1)。那只能带来灾难,因为在\*results.end()没有对象,\*(results.end()+1)也 没有!调用transform是错误的,因为它会给不存在的对象赋值. ### 正确使用transform ***** 把transform的结果放入 叫做results容器的结尾”的方式是调用back\_inserter来产生指定目标区间起点的迭代器: ``` vector results; // 把transmogrify应用于 transform(values.begin(), values.end(), // values中的每个对象, back_inserter(results), // 在results的结尾 transmogrify); // 插入返回的value ``` 所以你可以在任何提供push\_back的容器上使用 back\_inserter,如果你想让一个算法在容器的前端插入东西,你可以使用front\_inserter。在内部,front\_inserter利用了push\_front。所以front\_insert只和提供front_back成 员函数的容器配合(也就是deque和list): ``` ... // 同上 list results; // results现在是list transform(values.begin(), values.end(), // 在results前端 front_inserter(results), // 以反序 transmogrify); // 插入transform的结果 ``` ### inserter的使用 ***** inserter允许你强制算法把它们的结果插入容器中的任意位置: ``` vector values; // 同上 ... vector results; // 同上,除了现在 ... // 在调用transform前 // results已经有一些数据 transform(values.begin(), values.end(), // 把transmogrify的 inserter(results, results.begin() + results.size()/2), // 结果插入 transmogrify); // results的中间 ``` ### 确保目标区间足够大 ***** 条款5解释了对于连续内存容器插入数据需要用到区间函数,但是transform会对目的区间每次写入一个值,你无法改变。 当你要插入的容器是vector或string时,你可以通过按照条款14的建议最小化这个代价,预先调用reserve。 ``` vector values; // 同上 vector results; results.reserve(results.size() + values.size()); // 同上 transform(values.begin(), values.end(), // 把transmogrify的结果 back_inserter(results), // 写入results的结尾, transmogrify); // 处理时避免了重新分配 ```