15
  • vector::operator= 是否改变向量容量?如果是这样,怎么做?
  • 向量的复制构造函数是否复制容量?

我查看了文档,但找不到具体的答案。它依赖于实现吗?

4

5 回答 5

9

您可以保证的是:

  1. 向量有足够的容量来存储它的元素。(明显地。)
  2. 在当前容量已满之前,向量不会获得新容量。*

因此,实现想要增加多少额外或减少多少取决于实现。我认为大多数人会在复制时使容量匹配大小,但不能降低容量。(因为上面的第 2 点;不允许在有足够空间的情况下重新分配。)

* 大多数情况下。请参阅下面查尔斯的评论。

于 2010-04-18T17:29:48.637 回答
2

vector::operator= 是否改变向量容量?如果是这样,怎么做?

它可能会改变容量。仅当先前的容量太小而无法容纳新容量时才会发生这种情况。如果是这样,则新容量至少等于新大小,但可能是更大的值。

复制构造函数是否复制容量?

根据 C++03 中的表 65 容器要求,X u (a);并且X u = a;都等效于X u; u = a;. 在默认构造向量之后,这使得复制 ctor 与 op= 情况相同。

于 2010-04-18T18:43:36.380 回答
1

正如我之前写的,副本不需要——通常也不需要——保留原始向量的容量。

gcc version 4.1.1

$ cat vt.cpp
#include <vector>
#include <iostream>
int main() {
   std::vector<int> v1;
   v1.reserve(50000);
   std::vector<int> v2 = v1;
   std::cout << v1.capacity() << std::endl;
   std::cout << v2.capacity() << std::endl;
   return 0;
}

$ g++ vt.cpp -o vt && ./vt
50000
0

$ cat v2.cpp
#include <vector>
#include <iostream>
int main() {
   std::vector<int> v1;
   v1.reserve(50000);
   std::vector<int> v2;
   v2 = v1;
   std::cout << v1.capacity() << std::endl;
   std::cout << v2.capacity() << std::endl;
   return 0;
}

$ g++ v2.cpp -o v2 && ./v2
50000
0
于 2010-04-18T17:53:33.570 回答
0
  1. 正如下面的 SGI STL 向量源代码所示,operator=将为恰好n 个元素保留空间,即_M_end_of_storage = _M_start + __xlen; .
    template <class _Tp, class _Alloc>
    vector<_Tp,_Alloc>&
    vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)
    {
      if (&__x != this) {
        const size_type __xlen = __x.size();
        if (__xlen > capacity()) {
          iterator __tmp = _M_allocate_and_copy(__xlen, __x.begin(), __x.end());
          destroy(_M_start, _M_finish);
          _M_deallocate(_M_start, _M_end_of_storage - _M_start);
          _M_start = __tmp;
          _M_end_of_storage = _M_start + __xlen;
        }
        else if (size() >= __xlen) {
          iterator __i = copy(__x.begin(), __x.end(), begin());
          destroy(__i, _M_finish);
        }
        else {
          copy(__x.begin(), __x.begin() + size(), _M_start);
          uninitialized_copy(__x.begin() + size(), __x.end(), _M_finish);
        }
        _M_finish = _M_start + __xlen;
      }
      return *this;
    }
  1. 正如下面的 SGI STL 向量源代码所示,vector 的复制构造函数将为正好n 个元素保留空间,即_M_end_of_storage = _M_start + __n; .
      template <class _InputIterator>
      vector(_InputIterator __first, _InputIterator __last,
             const allocator_type& __a = allocator_type()) : _Base(__a) {
        typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
        _M_initialize_aux(__first, __last, _Integral());
      }

      template <class _Integer>
      void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) {
        _M_start = _M_allocate(__n);
        _M_end_of_storage = _M_start + __n;
        _M_finish = uninitialized_fill_n(_M_start, __n, __value);
      }
于 2020-05-28T06:54:55.360 回答
-2

它取决于实现。大多数实践中将向量缩小到最小大小。

于 2010-04-18T17:29:12.677 回答