另一方面,如果源的大小大于目的地的容量并进行重新分配,是否要求重新分配与源的容量相关(例如,目的地的新容量应不小于源的容量,甚至要求它们相同)?或者重新分配只是根据新的规模完成工作(不考虑源的容量)
对于移动分配,我认为不会进行存储重新分配(虽然我没有找到标准中的相关部分),但是这意味着目标的新容量的价值将与源的旧容量完全相同?我可以期待v = vector< T> {};具有与矢量< T> {}相同的效果.swap(v);?
我想这个答案被埋在标准的某个地方,但是我没有找到它们.
(如果C 11和C 03的情况不同,我想了解两者的各种要求.)
PS:对于上述问题的任何答案,对于std :: string(仅在C 11中意思是连续存储,没有COW,C 03字符串不在雷达中)是否相同?
解决方法
std::vector<T,A>( std::vector<T,A>&& )
这被保证是恒定的时间(N3797表99 X u(rv)).
没有任何方法可以自己移动一个任意大小的向量在不变的时间,而不必将指针移动到缓冲区.如果这样(没有办法)为真,则构造的向量必须至少具有与源缓冲区一样大的缓冲区.标准中没有任何措辞说明向量需要有效,但右手侧向量可以将其容量减小到大于或等于其大小的任何值:后置条件只是元素相同.在理论上,如果右手侧的向量具有编译器选择暴露的“隐藏能力”,那么甚至可能是更大的容量(说明月球的阶段).
N3797标准中的任何一点都不是放在任何容器上的容量的上限.一致的实现可以使所有的std ::向量具有至少200万的元素容量(禁止分配器失败 – 可以用来强制容量为0),没有操作能够将该值降低到200万以下. (shrink_to_fit只是一个建议,std :: vector< T,A>().swap(x)可以创建200万容量的向量并进行交换.
上面所说的都是一个负面的形式,我可以说是搜索标准,以提供向量,分配器,分配和容量.容量在任何时候都不会用上限描述.在空std :: vector构造函数中,对分配器的额外调用没有限制(如果分配器失败,则可能需要保持0和容量0,但是将该状态提取到使用相同的分配器是具有挑战性的).
对于副本分配和移动分配,副本分配不会超出最基本的(该容量()> = size())的容量保证.
对于移动分配,这取决于如何适用:
23.2.1 [container.requirements.general] / 10
Unless otherwise specified (either explicitly or by defining a function in terms of other functions),invoking a
container member function or passing a container as an argument to a library function shall not invalidate
iterators to,or change the values of,objects within that container.
表96和表99中的a = rv(aka std :: vector< T,A>& operator =(std :: vector< T,A>&&&&没有提到rv中包含的值被破坏,也不会使对它们的迭代器无效.因此,在23.2.1 / 10下,迭代器不会失效.
但是,这并不要求缓冲区移动.缓冲区从rhs移动到lhs,或者在rhs载体中保持完整.表99提到这种情况,当它表示lhs项目可以移动分配给(这是std ::数组可以工作的唯一方式)时,这是隐含的.
由于std ::数组不得不移动元素,而std :: vector对移动缓冲区没有任何进一步的保证,缓冲区不必被移动.看来,移动缓冲区是一种合法的实现.
在实践中,A>(std :: vector< T,A> const&)将执行右侧内容的副本进入左侧,左侧的容量等于所得到的矢量的大小.类似地,A>(ForwardIterator,ForwardIterator)将产生适合其输入的向量.
注意,A> :: operator =(std :: vector< T,A>&&)在复杂性中保持线性.