C++ 带反向插入器的复制算法
我不明白为什么这个代码是准确的C++ 带反向插入器的复制算法,c++,stl-algorithm,C++,Stl Algorithm,我不明白为什么这个代码是准确的 vector<int> coll; coll.reserve(2*coll.size()); copy ( coll.begin(), coll.end(), // zrodlo back_inserter(coll) // przeznaczenie ); coll.end() coll.reserve(2*coll.size()); auto oldEnd = coll.end(); copy (coll.begi
vector<int> coll;
coll.reserve(2*coll.size());
copy (
coll.begin(), coll.end(), // zrodlo
back_inserter(coll) // przeznaczenie
);
coll.end()
coll.reserve(2*coll.size());
auto oldEnd = coll.end();
copy (coll.begin(), oldEnd, back_inserter(coll) );
这意味着,copy
不会重新计算coll.end()
,因此它不会注意到/打扰到它正在插入同一个向量,并且曾经是向量结尾的内容不是第一次插入后的结尾
同样的算法不会编译列表,因为std::list
没有reserve
方法。但是,如果没有reserve
,它应该适用于list
s,因为std::list::push_back
不会使迭代器无效。
您是对的,std::vector::push_back
在重新分配时使迭代器无效,因此执行reserve
调用非常重要,因为它确保不需要重新分配 调用函数时,将对用于确定要复制内容的begin()
和end()
指针/迭代器求值一次。所以本质上,std::copy()
会增加它的游标迭代器,最终到达end()
,因为vector::const_迭代器
只是一个老式数组上的一个奇特的T*
指针
正如您正确提到的,如果推回使向量重新分配并将数据移动到内存中的其他位置,那么复制的下一个元素将具有错误的源地址,这可能最终导致分段错误
对于列表,它永远不能终止,因为end()
是一个sentinel/guard指针,您只能通过增加列表最后一个元素上的迭代器来达到end()
。因此end()
本身的地址永远不会更改,但由于您不断在列表末尾添加元素,因此永远不会到达最后一个元素,因此std::copy()
永远无法获得指向end()
的指针。有点像狗在追它的尾巴
通过插图和图表更容易理解,阅读双链接列表和sentinel节点,这一切都会有意义。我知道列表中没有保留()。我已经尝试了列表的代码。程序进入了无休止的循环。您能给我们看一下您用来测试列表中那个程序的[SSCCE](http://SSCCE.org)代码吗?
coll.reserve(2*coll.size());
auto oldEnd = coll.end();
copy (coll.begin(), oldEnd, back_inserter(coll) );