请考虑以下代码:
std::vector vec;
vec.reserve(500);
size_t cap = vec.capacity();
std::vector newVec = std::move(vec);
assert(cap == newVec.capacity());
在你遇到的任何实现中,这都可行。我不关心实现什么。我想知道标准需要什么。移动到vector
的容量是否与原始容量相同?或者断言会触发吗?
答案 0 :(得分:11)
看看标准,似乎移动构造函数不需要任何东西,但是正如@amaurea所说,如果移动构造函数尝试分配或释放内存,它将彻底打败移动语义的目的,所以我会期望所有实施中的容量保持不变。
23.2.1一般容器要求
表达
X u(a);
X u = a;
断言/注意前/后条件
要求:T
是CopyInsertable到X(见下文)
发布:u == a
该标准仅要求newVec == vec
。由于std::vector::operator==
未考虑容量,newVec
无需具有与vec
相同的容量。
答案 1 :(得分:9)
对std::vector
的移动构造函数的C ++ 11标准要求是(表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
时保留容量,存储可能会缩小。