20

考虑以下代码:

std::vector vec;
vec.reserve(500);
size_t cap = vec.capacity();

std::vector newVec = std::move(vec);
assert(cap == newVec.capacity());

在您遇到的几乎任何实现中,这都会起作用。我不在乎实现是做什么的。我想知道标准要求什么。搬家的vector容量和原来的一样吗?还是断言会触发?

4

2 回答 2

12

查看标准,移动构造函数似乎不需要任何东西,但是正如@amaurea 所说,如果移动构造函数尝试分配或释放内存,它将完全违背移动语义的目的,所以我希望容量在所有实现中保持不变。


23.2.1 一般容器要求

表达

X u(a);
X u = a;

断言/注释前置/后置条件

要求:T是否可 CopyInsertable 到 X 中(见下文)。
邮政:u == a


该标准仅要求newVec == vec. 由于不考虑容量std::vector::operator==newVec所以不一定要具有相同的容量vec

于 2012-10-29T20:49:30.197 回答
9

移动构造函数的 C++11 标准要求std::vector是(表 99 - 分配器感知容器要求):

X(rv)
X u(rv)
  • 分配器的移动构造不应通过异常退出
  • rv帖子:你应该有与此构造之前相同的元素;的值get_allocator()应与rv.get_allocator()本次施工前的值相同。
  • 复杂性:常数

这里对容量没有要求/保证。但是我们可以得出结论,恒定的复杂性隐含地否认了任何重新分配。除了重新分配之外,我看不到任何其他改变容量的合乎逻辑的理由。所以应该是一样的。

从另一个角度来看,如果移动的向量是空的,那么忽略它并默认构造本身是完全合法的。这仍然是 O(1),因为它不需要任何每个元素的构造。(感谢Nicol Bolas的这个问题)。

实现也可能使用函数hint参数将容量缩小到大小std::allocator::allocate

pointer allocate(size_type, allocator<void>::const_pointer hint = 0);

未指定使用hint,但如果实现需要,则旨在帮助本地化。所以一些复杂的解决方案可能会传递向量存储指针hint并使用realloc它来缩小容量。

结论:看起来标准并不能保证移动时保持容量std::vector,存储可能会缩小。

于 2012-10-29T21:11:44.453 回答