引发这个问题的是一些代码:
std::vector<int> x(500);
std::vector<int> y;
std::swap(x,y);
Run Code Online (Sandbox Code Playgroud)
我想知道交换两者是否需要两倍的内存量x
。
在cppreference上我找到了 for std::vector::swap
(这是最后一行有效调用的方法):
将容器中的内容物与其他容器中的内容物交换。不会对单个元素调用任何移动、复制或交换操作。
所有迭代器和引用仍然有效。尾后迭代器无效。
现在我比以前更困惑了。std::vector::swap
当它不移动、复制或交换元素时,它实际上会做什么?迭代器如何保持有效?
这是否意味着这样的代码是有效的代码?
std::vector<int> x(500);
std::vector<int> y;
auto it = x.begin();
std::swap(x,y);
std::sort(it , y.end()); // iterators from different containers !!
Run Code Online (Sandbox Code Playgroud)
vector
内部存储(至少)一个指向元素实际存储的指针、大小和容量。\xe2\x80\xa0 std::swap
只是交换指针、大小和容量(以及辅助数据,如果有);不会进行内存加倍或元素副本,因为 in 的指针x
变为 in 的指针y
,反之亦然,而无需分配任何新内存。
的迭代器vector
通常是指向底层分配内存的指针的轻量级包装器(这就是为什么容量更改通常会使迭代器无效),因此在x
之前生成的迭代器swap
可以无缝地继续引用y
; 之后的迭代器swap
。您的示例使用sort
是合法的,并且排序y
。
如果您想交换元素本身而不交换存储(这是一种更昂贵的操作,但会留下预先存在的迭代器来x
引用x
),您可以使用std::swap_range
,但这是一个相对不常见的用例。其内存使用量取决于swap
底层对象的实现;默认情况下,它通常会涉及临时对象,但一次仅交换一个对象,而不是整个对象vector
。
\xe2\x80\xa0根据注释,它可以等效地使用指向已用空间末尾和容量末尾的指针,但两种方法在逻辑上都是等效的,只是微优化以支持稍微不同的预期用例;存储所有指针可优化迭代器的使用(合理的选择),而存储size_type
可优化.size()
/.capacity()
调用。