Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 容量是否复制到向量中?_C++_Vector - Fatal编程技术网

C++ 容量是否复制到向量中?

C++ 容量是否复制到向量中?,c++,vector,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); std::向量a; a、 储备(65536); std::载体b(a)//注:b由a构成 a、 保留地(65536);//没有再分配 b、 储备(6553

以下面的代码为例:

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);
std::向量a;
a、 储备(65536);
std::载体b(a)//注:b由a构成
a、 保留地(65536);//没有再分配
b、 储备(65536);

是否复制了容量?最后一行会重新分配吗?标准对此有什么说明吗?还是没有说明?

好吧,下面这样一个简单的检查表明容量没有被复制:

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
std::向量a;
a、 储备(65536);

当您调用复制构造函数时,cout标准并没有说明如何保持容量。所以你对此没有任何保证

但是,如果只需要保留副本中的容量,可以使用以下技巧交换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); 
std::向量a;
a、 储备(65536);
std::载体b(a);
b、 互换(a);//现在b有a的状态
断言(b.容量()==65536);
是否复制了容量

实际上,没有。我在和中在线测试了它,没有一个复制了容量

最后一行会重新分配吗

如果容量小于要保留的参数(即,它不会被复制),则为是

标准对此有什么规定吗?还是没有规定

中未提供复制构造函数的定义。相反,我们必须看看

X
表示包含类型为
T
a
的对象的容器类
b
表示
X
类型的值,
u
表示标识符,
r
表示 类型为
X
rv
的非常量值表示 键入
X

xu(a)

xu=a

要求:
T
CopyInsertable
插入
X
(见下文)

post:
u==a

两个容器相等意味着什么

a==b

=
是一种等价关系<代码>相等(a.开始(),a.结束(),b.开始(),b.结束())


换句话说,因为它不要求
容量
在比较中相等,所以没有理由复制
容量

不,容量不保证由
向量
复制构造来保持

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

vector<int> b;
b.reserve( a.capacity() );
b = a;
向量b;
b、 储备(a.容量());
b=a;
更好地封装在函数中

  • 正如SGI STL矢量soruce代码如下所示,运算符=将为n元素保留空间,即\u存储的\u M u end\u=\u开始+\uxlen
  • 模板
    载体&
    向量::运算符=(常量向量和x)
    {
    如果(&x!=此){
    const size_type_uuxlen=uuuux.size();
    如果(\uxlen>capacity()){
    迭代器\uuuTMP=\uM\uAllocate\u和\uCopy(\uuxlen,\uuux.begin(),\uuuuux.end());
    销毁(开始、结束);
    _M_解除分配(_M_开始,_M_结束\u存储-_M_开始);
    _M_开始=u tmp;
    _存储器的M_end_=_M_start+_xlen;
    }
    否则如果(大小()>=\uxLen){
    迭代器i=copy(uuux.begin(),uuux.end(),begin());
    销毁(i,M,finish);
    }
    否则{
    复制(uuu x.begin(),uuu x.begin()+大小(),u M_start);
    未初始化的拷贝(uuu x.begin()+size(),uuu x.end(),u M_finish);
    }
    _M_finish=_M_start+_xlen;
    }
    归还*这个;
    }
    
  • 正如SGI STL vector soruce代码如下所示,vector的复制构造函数将为n元素保留空间,即\U end\U of_storage=\u M_start+\u n
  • 模板
    向量(_inputierator uu first,_inputierator u last,
    常量分配器类型(&\u a=allocator\u type()):\u基(\u a){
    typedef typename_是_整数::_Integral_Integral;
    _M_initialize_aux(u first,u last,_Integral());
    }
    模板
    void\u M\u initialize\u aux(\u Integer\u n,\u Integer\u value,\u true\u type){
    _M_开始=_M_分配(u n);
    _存储的M_end_=_M_start+u n;
    _M_finish=未初始化的填充(_M_start,_n,_值);
    }
    
    在vector c-tors文档中,声明它复制元素。可能的重复表明您的特定实现没有复制容量。它不会告诉您这是否是一个bug。这只是交换
    reserve
    调用将导致重新分配的内容。交换不使用分配器,只交换对象的状态。因此,您可以交换具有不同分配器的向量吗?如果是这样,它就不能只交换分配的单个内存块。@JDługosz具有不同分配器类型的两个向量是不同的向量类型,因此不能交换它们。@AnatolyS这在C++11中是不正确的。在C++03分配器中,要求是无状态的,因此“swap对分配器不做任何事情”的语句在某种程度上是正确的。在C++11中,有关分配器的
    swap
    行为是由
    allocator\u traits::propagate\u on_container\u swap
    @P0W定制的。我看不到链接到rextester上的直接代码示例的简单方法。
        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;
        }
    
          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);
          }