Nic*_*las 18 c++ stdvector language-lawyer move-semantics c++11
请考虑以下代码:
std::vector vec;
vec.reserve(500);
size_t cap = vec.capacity();
std::vector newVec = std::move(vec);
assert(cap == newVec.capacity());
Run Code Online (Sandbox Code Playgroud)
在几乎任何你遇到的实现中,这都可行.我不关心实现什么.我想知道标准需要什么.移动的vector容量是否与原始容量相同?或者断言触发器?
Pet*_*der 11
看看标准,似乎移动构造函数不需要任何东西,但是正如@amaurea所说,如果移动构造函数试图分配或释放内存,它将完全打败移动语义的目的,所以我希望能力在所有实现中保持不变.
23.2.1一般容器要求
表达
X u(a);
X u = a;
Run Code Online (Sandbox Code Playgroud)
断言/说明前/后条件
要求:TCopyInsertable是否为X(见下文).
职位:u == a
标准只要求newVec == vec.由于不考虑容量std::vector::operator==,newVec不一定需要具有相同的容量vec.
移动构造函数的C++ 11标准要求std::vector是(表99 - 可识别分配器的容器要求):
X(rv)
X u(rv)
Run Code Online (Sandbox Code Playgroud)
rv此建筑之前相同的元素; 值get_allocator()应与rv.get_allocator()此结构前的值相同.这里没有要求/保证容量.但我们可以得出结论,不变的复杂性隐含地否认任何重新分配.除了重新分配之外,我看不到任何其他合理的理由来改变容量.所以它应该是一样的.
从另一个角度来看,如果移动的向量是空的,那么忽略它并默认构造自身是完全合法的.这仍然是O(1),因为它不需要任何每元素结构.(感谢Nicol Bolas的这个问题).
也可以使用函数hint参数实现将容量缩小到大小std::allocator::allocate:
pointer allocate(size_type, allocator<void>::const_pointer hint = 0);
Run Code Online (Sandbox Code Playgroud)
使用hint未指定,但如果实施需要,则旨在帮助当地.所以一些软化的解决方案可能会传递矢量存储指针,hint并使用realloc它来缩小容量.
结论:看起来标准不保证移动时的容量保留std::vector,存储可能会缩小.