复制后的std::向量容量

问题描述 投票:14回答:5
  • vector::operator=会改变向量容量吗? 如果是,如何改变?
  • vector的copy构造函数会复制容量吗?

我查看了文档,但没有找到具体的答案。 它是否依赖于实现?

c++ stl vector capacity
5个回答
9
投票

你能保证的就是。

  1. 向量有足够的容量来存储它的元素。(很明显。)
  2. 向量不会得到新的容量,直到它的当前容量满了为止*。

所以,一个实现想多放或少放多少是由实现决定的。我想大多数会让容量与大小相匹配,复制时,但不能降低容量。(因为上面第2条,在空间足够的情况下,不允许重新分配)。

* 大多数情况下是这样。参见下面 Charles 的评论。


2
投票

vector::operator= 是否会改变向量的容量?如果是,如何改变?

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

复制构造函数会复制容量吗?

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


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

0
投票
  1. 正如SGI STL向量soruce代码所示。操作者= 将保留空间为 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向量soruce代码所示,向量的 抄写员 将保留空间为 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);
      }

-2
投票

这取决于实现。大多数在实践中都会将向量收缩到最小尺寸。

© www.soinside.com 2019 - 2024. All rights reserved.