STL提供的三种插入迭代器——back_insert_iterator、front_insert_iterator和insert_iterator来提供STL算法的通用性。很多STL函数都与copy()相似,将结果发送到输出迭代器指示的位置(也就是dice.begin()开始的位置)
copy(casts, casts + 10, dice.begin());
这些值将覆盖dice中以前的内容,且该函数假设dice有足够的空间,能够容纳这些值,即copy()不能自动根据发送值调整目标容器的长度。但是,如果预先并不知道dice的长度,该如何办呢?或者要将元素添加到dice中,而不是覆盖已有的内容,又该如何办呢?
三种插入迭代器通过将复制转换为插入解决了这些问题。插入将添加新的元素,而不会覆盖已有的数据,并使用自动内存分配来确保能够容纳新的信息。back_insert_iterator将元素插入到容器的尾部,而front_insert_iterator将元素插入到容器的前端。最后,insert_iterator将元素插入到insert_iterator构造函数的参数指定的位置前面。这三个插入迭代器都是输出容器概念的模型。
这里存在一些限制。back_insert_iterator只能用于允许在尾部快速插入的容器(快速插入指的插入数据的时间不随容器元素数目增加而增加),vector类符合这种要求。front_insert_iterator只能用于允许在其实位置做快速插入的容器类型,vector类不能满足这种要求,但queue满足。insert_iterator没有这些限制,因此可以用它把信息插入到矢量的前端。然而,front_insert_iterator对于那些支持它的容器来说,完成任务的速度更快。
这些迭代器将容器类型作为模板参数,将实际的容器标识符作为构造函数参数。也就是说,要为名为dice的vector< int>容器创建一个back_insert_iterator,可以这样做:
back_insert_iterator<vector<int>> back_iter(dice);
必须声明容器类型的原因是,迭代器必须使用合适的容器方法。back_insert_iterator的构造函数将假设传递给它的类型有一个push_back()方法。copy()是一个独立的函数,没有重新调整容器大小的权限。但前面的声明让back_iter能够使用方法vector< int>::push_back(),该方法有这样的权限。
声明front_insert_iterator的方式与此相同。对于insert_iterator声明,还需要一个指示插入位置的构造参数:
insert_iterator<vector<int>> insert_iter(dice, dice.begin());
示例
#include <iostream>
#include <string>
#include <iterator>
#include <vector>
#include <algorithm>
void output(const std::string &s) { std::cout << s << std::endl; }
int main()
{
using namespace std;
string s1[4] = { "find", "fish", "fashion", "fate" };
string s2[2] = { "busy", "bats" };
string s3[2] = { "silly", "singers" };
vector<string> word(4);
copy(s1, s2 + 4, words.begin());
for_each(words.begin(), words.end(), output);
cout << endl;
// construct anonymous back_insert_iterator object
copy(s2, s2 + 2, back_insert_iterator<vector<string>>(words));
for_each(words.begin(), words.end(), output);
cout << endl;
// construct anonymous insert_iterator object
copy(s3, s3 + 2, insert_iterator<vector<string>>(words, words.begin());
for_each(words.begin(), words.end(), output);
cout << endl;
return 0;
}