容量是否在向量中复制?

时间:2016-06-05 07:12:40

标签: c++ vector

请使用以下代码:

std::vector<int> a;
a.reserve(65536);
std::vector<int> b(a);  //NOTE: b is constructed from a

a.reserve(65536); // no reallocation
b.reserve(65536);

是否复制了容量?最后一行会有重新分配吗?标准是否对此有所说明或是否保持沉默?

5 个答案:

答案 0 :(得分:42)

  

是否复制了容量?

在实践中,没有。我在Clang and GCC以及MSVC在线测试了它,但没有一个复制容量。

  

最后一行会有重新分配吗?

如果容量小于保留的参数(即它没有被复制),那么是。

  

标准是否对此有所说明或是否保持沉默?

vector.cons中未提供复制构造函数的定义。相反,我们必须查看container.requirements

  

X表示包含Ta和类型的对象的容器类   b表示类型X的值,u表示标识符,r表示   类型为X的非const值,rv表示非const值   输入X

     

X u(a)

     

X u = a;

     

要求: T CopyInsertableX(见下文)。

     

发布:u == a

现在两个容器相同意味着什么?

  

a == b

     

==是一种等价关系。 equal(a.begin(), a.end(), b.begin(), b.end())

换句话说,由于在比较中不需要capacity,因此没有理由复制capacity

答案 1 :(得分:4)

Standard在调用复制构造函数时没有说明保留容量。所以你对它没有任何保证。

但是,如果您只需要在副本中保留容量,则可以执行以下操作,即交换a和b的状态:

 std::vector<int> a;
 a.reserve(65536);
 std::vector<int> b(a);
 b.swap(a); // now b has a's state
 assert(b.capacity() == 65536); 

答案 2 :(得分:4)

不,vector复制结构不能保证容量。

您可以按照以下方式执行此操作:

vector<int> b;
b.reserve( a.capacity() );
b = a;

更好地封装在一个函数中。

答案 3 :(得分:1)

嗯,如下所示的简单检查表明容量未被复制:

std::vector<int> a;
a.reserve(65536);
cout << "a.capacity is " << a.capacity() << endl; // prints 65536

std::vector<int> b(a);  //NOTE: b is constructed from a
cout << "b.capacity is " << b.capacity() << endl; // prints 0

我相信在将向量a复制到b后,b的容量在大多数编译器中设置为a的大小;虽然这不能保证。

答案 4 :(得分: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向量源代码显示,向量的复制构造函数将为 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);
      }