向量分配是否会使`reserve`无效? [英] Does a vector assignment invalidate the `reserve`?

查看:51
本文介绍了向量分配是否会使`reserve`无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我写

std::vector<T> littleVector(1);
std::vector<T> bigVector;

bigVector.reserve(100);
bigVector = littleVector;

标准是否说bigVector仍将保留100个元素?还是要push_back 99个元素,我会遇到内存重新分配的情况?也许甚至在STL实现之间也有所不同.

Does the standard say that bigVector will still have 100 elements reserved? Or would I experience memory reallocation if I were to push_back 99 elements? Perhaps it even varies between STL implementations.

以前在此处对此进行了讨论,但未提供标准参考.

This was previously discussed here but no Standard references were given.

推荐答案

不幸的是,该标准未充分说明可识别分配器的序列容器分配的行为,并且确实严格地说是不一致的.

Unfortunately, the standard underspecifies behavior on allocator-aware sequence container assignment, and indeed is strictly speaking inconsistent.

(从表28和23.2.1p7)我们知道,如果allocator_traits<allocator_type>::propagate_on_container_copy_assignment::valuetrue,则分配器在复制分配时被替换.此外,从表96和表99中,我们发现副本分配的 complexity linear ,而操作a = t post-condition a == t,即(表96)distance(a.begin(), a.end()) == distance(t.begin(), t.end()) && equal(a.begin(), a.end(), t.begin()).从23.2.1p7开始,在复制分配之后,如果分配器传播,则a.get_allocator() == t.get_allocator().

We know (from Table 28 and from 23.2.1p7) that if allocator_traits<allocator_type>::propagate_on_container_copy_assignment::value is true then the allocator is replaced on copy assignment. Further, from Tables 96 and 99 we find that the complexity of copy assignment is linear, and the post-condition on operation a = t is that a == t, i.e. (Table 96) that distance(a.begin(), a.end()) == distance(t.begin(), t.end()) && equal(a.begin(), a.end(), t.begin()). From 23.2.1p7, after copy assignment, if the allocator propagates, then a.get_allocator() == t.get_allocator().

关于向量容量,23.3.6.3 [vector.capacity] 具有:

With regard to vector capacity, 23.3.6.3 [vector.capacity] has:

5-备注:重新分配会使引用序列中元素的所有引用,指针和迭代器无效.可以保证在调用reserve()之后直到插入使向量的大小大于capacity()的值之前,在插入期间不会发生重新分配.

5 - Remarks: Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. It is guaranteed that no reallocation takes place during insertions that happen after a call to reserve() until the time when an insertion would make the size of the vector greater than the value of capacity().

如果我们以库DR341 作为指南阅读标准:

If we take library DR341 as a guide to reading the Standard:

但是,在调用reserve()之后,第23.3.6.3 [vector.capacity]段5的措词可以防止向量的容量减少.这使成语无效,因为这样可以防止swap()减少容量. [...]

However, the wording of 23.3.6.3 [vector.capacity]paragraph 5 prevents the capacity of a vector being reduced, following a call to reserve(). This invalidates the idiom, as swap() is thus prevented from reducing the capacity. [...]

DR341已通过在23.3.6.3中添加段落来解决:

DR341 was resolved by adding paragraphs into 23.3.6.3:

void swap(vector<T,Allocator>& x);
7-效果:*this的内容和capacity()x的内容和capacity()交换.
8-复杂度:恒定时间.

void swap(vector<T,Allocator>& x);
7 - Effects: Exchanges the contents and capacity() of *this with that of x.
8 - Complexity: Constant time.

结论是,从图书馆委员会的角度来看,只有在23.3.6.3中提到的情况下,操作才会修改capacity().在23.3.6.3中未提及副本分配,因此不会修改capacity(). (移动分配具有相同的问题,尤其是考虑到对图书馆DR2321提出的决议.)

The conclusion is that from the point of view of the Library committee, operations only modify capacity() if mentioned under 23.3.6.3. Copy assignment is not mentioned under 23.3.6.3, and thus does not modify capacity(). (Move assignment has the same issue, especially considering the proposed resolution to Library DR2321.)

显然,这是标准中的缺陷,因为复制分配传播的不相等分配器必须导致重新分配,这与23.3.6.3p5相矛盾.

Clearly, this is a defect in the Standard, as copy assignment propagating unequal allocators must result in reallocation, contradicting 23.3.6.3p5.

我们可以期望并希望此缺陷得到解决,有利于:

We can expect and hope this defect to be resolved in favour of:

  • 在未修改分配器的副本分配上未缩减的capacity()
  • 未指定capacity()有关修改分配器的副本分配;
  • 非分配器传播的移动分配上的非缩减capacity()
  • 源容器capacity()有关分配器传播的移动分配.
  • non-reduced capacity() on non-allocator-modifying copy assignment;
  • unspecified capacity() on allocator-modifying copy assignment;
  • non-reduced capacity() on non-allocator-propagating move assignment;
  • source-container capacity() on allocator-propagating move assignment.

但是,在当前情况下,直到明确这一点,您最好不要依赖任何特定的行为.幸运的是,有一个简单的解决方法可以保证不减少capacity():

However, in the current situation and until this is clarified you would do well not to depend on any particular behavior. Fortunately, there is a simple workaround that is guaranteed not to reduce capacity():

bigVector.assign(littleVector.begin(), littleVector.end());

这篇关于向量分配是否会使`reserve`无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆