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) );