[英]What's the difference between iterator and back_insert_iterator?
如果随机访问迭代器可以用于访问相对于它们指向的元素的任意偏移位置的元素(不知何故像指针),为什么不能在std::copy()
等通用算法中使用它们而不是使用back_insert_iterator
,两者之间有什么区别?
std::back_insert_iterator
是一种特定的输出迭代器,它支持push_back
操作。 当您使用operator=
写入它时,它会将值push_backs到底层容器中 - 因此,从这个意义上说,它充当具有push_back
成员函数的容器的适配器。
一个例子很容易理解:
std::vector<int> v;
std::back_insert_iterator<std::vector<int>> it(v);
*it = 10; // it is equivalent to v.push_back(10);
it = 99; // it is ALSO equivalent to v.push_back(99);
for (auto const & i : v)
std::cout << i << " " ; //10 99
它输出:
10 99
在线演示 。
通常的迭代器操作++
和*
it
没有影响。
但是你很少直接使用它们(我从未直接使用它直到现在)。 您可以将它们与算法一起使用,例如std::copy
在这种情况下,您还可以使用std::back_inserter
函数返回std::back_insert_iterator
类型的对象。
//assuming dest is a container which supports push_back!
std::copy(src.begin(), src.end(), std::back_inserter(dest));
您还希望看到以下(适配器)迭代器:
push_front
操作 insert
操作。 因此,根据容器,您选择适配器迭代器。
请注意,它们都是输出迭代器。
为什么不能在std :: copy()等通用算法中使用它们而不是使用back_insert_iterator。
当然,您可以在std::copy
等算法中使用随机访问迭代器(或任何输出迭代器)作为第三个参数,但是假设迭代器引用现有范围 - *it
和++it
是明确定义的你传递的价值。 您传递它们以覆盖范围的现有元素,而std::back_insert_iterator
将新元素添加到容器中。
希望有所帮助。
实际上,你可以在std::copy
完全使用常规迭代器。
int main() {
std::vector<int> vec{1, 2, 3, 4};
std::list<int> list{vec.size()};
std::copy(vec.begin(), vec.end(), list.begin());
// list = 1, 2, 3, 4
}
但是,正如您可能注意到的,这意味着:
len(source range)
默认元素 这是非常低效的,并且要求元素可以默认构造然后分配给。
相反, back_insert_iterator
是一个伪迭代器,它作为普通容器上的适配器运行。 如果你看一下界面,你会发现它根本不像常规迭代器那样,只要你试图推送一个项目,就会在它嵌入的底层容器引用上调用push_back
。
int main() {
std::list<int> list;
std::back_insert_iterator<std::list<int>> bii(list);
bii = 1;
bii = 2;
bii = 3;
bii = 4;
// list = 1, 2, 3, 4
// note: decltype(*bii) == bii&, so deferencing bii serves no purpose;
// similarly, ++bi does nothing either; both operations are just defined
// to mimick a regular operator interface so it can be used in regular
// algorithms over iterators.
}
因此,这两种方法同样有效,但具有不同的行为:
back_insert_iterator
允许您追加到现有容器 语义是不同的,选择对手头的任务有意义。
常规迭代器对它们正在使用的容器一无所知,除了它所持有的数据类型。 为了向容器添加元素,让我们说一个向量,需要知道向量中的元素数量。
常规迭代器不会更改序列的大小或结构。 特别是随机访问迭代器只访问特定位置的元素。
std::back_insert_iterator<Cont>
是一个trmplate,它建模一个具体的输出迭代器,改变它所引用的每个元素所引用的序列:它为每个写入的元素调用cont.push_back()
。 由于迭代器不会读取它正在修改的序列,因此添加元素的效果非常好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.