容量是否在矢量中复制

Is capacity copied in a vector?

本文关键字:复制 是否 容量      更新时间:2023-10-16

获取以下代码:

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);

是否复制了容量?最后一行会重新分配吗?标准对此有什么规定吗?还是保持沉默?

是否复制了容量?

在实践中,没有。我在Clang和GCC以及MSVC中进行了在线测试,但他们都没有复制容量。

最后一行会重新分配吗?

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

标准对此有说明吗?还是保持沉默?

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

X表示包含类型为Tab表示类型X的值,u表示标识符,r表示X类型的非常值,并且rv表示类型CCD_ 10。

X u(a)

X u = a;

需要:TCopyInsertable转换为X(见下文)。

帖子:u == a

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

a == b

CCD_ 18是一个等价关系。equal(a.begin(), a.end(), b.begin(), b.end())

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

当您调用复制构造函数时,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); 

否,vector副本构造不能保证保留容量。

你可以这样做:

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

更好地封装在函数中。

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

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的大小;尽管这并不能保证。

  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);
}
相关文章: