请使用以下代码:
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);
是否复制了容量?最后一行会有重新分配吗?标准是否对此有所说明或是否保持沉默?
答案 0 :(得分:42)
是否复制了容量?
在实践中,没有。我在Clang and GCC以及MSVC在线测试了它,但没有一个复制容量。
最后一行会有重新分配吗?
如果容量小于保留的参数(即它没有被复制),那么是。
标准是否对此有所说明或是否保持沉默?
vector.cons中未提供复制构造函数的定义。相反,我们必须查看container.requirements
X
表示包含T
,a
和类型的对象的容器类b
表示类型X
的值,u
表示标识符,r
表示 类型为X
的非const值,rv
表示非const值 输入X
。
X u(a)
X u = a;
要求:
T
CopyInsertable
为X
(见下文)。发布:
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)
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);
}