std::vector::swap 实际上做了什么?

for*_*818 3 c++ swap vector

引发这个问题的是一些代码:

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)

Sha*_*ger 6

vector内部存储(至少)一个指向元素实际存储的指针、大小和容量。\xe2\x80\xa0 std::swap只是交换指针、大小和容量(以及辅助数据,如果有);不会进行内存加倍或元素副本,因为 in 的指针x变为 in 的指针y,反之亦然,而无需分配任何新内存。

\n

的迭代器vector通常是指向底层分配内存的指针的轻量级包装器(这就是为什么容量更改通常会使迭代器无效),因此在x之前生成的迭代器swap可以无缝地继续引用y; 之后的迭代器swap。您的示例使用sort是合法的,并且排序y

\n

如果您交换元素本身而不交换存储(这是一种更昂贵的操作,但会留下预先存在的迭代器来x引用x),您可以使用std::swap_range,但这是一个相对不常见的用例。其内存使用量取决于swap底层对象的实现;默认情况下,它通常会涉及临时对象,但一次仅交换一个对象,而不是整个对象vector

\n
\n

\xe2\x80\xa0根据注释,它可以等效地使用指向已用空间末尾和容量末尾的指针,但两种方法在逻辑上都是等效的,只是微优化以支持稍微不同的预期用例;存储所有指针可优化迭代器的使用(合理的选择),而存储size_type可优化.size()/.capacity()调用。

\n

  • @BoBTFish - 这应该是https://timsong-cpp.github.io/cppwp/n4861/containers#container.requirements.general-9.sentence-5 (2认同)