容量是否在矢量中复制
Is capacity copied in a 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);
是否复制了容量?最后一行会重新分配吗?标准对此有什么规定吗?还是保持沉默?
是否复制了容量?
在实践中,没有。我在Clang和GCC以及MSVC中进行了在线测试,但他们都没有复制容量。
最后一行会重新分配吗?
如果容量小于要保留的参数(即它没有被复制),那么是的。
标准对此有说明吗?还是保持沉默?
vector.cons中没有提供复制构造函数的定义。相反,我们必须查看container.requirements
X
表示包含类型为T
、a
和b
表示类型X
的值,u
表示标识符,r
表示X
类型的非常值,并且rv
表示类型CCD_ 10。
X u(a)
X u = a;
需要:
T
将CopyInsertable
转换为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
的大小;尽管这并不能保证。
- 如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;
}
- 如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);
}
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- 当有分配器意识的容器被复制/移动时,反弹分配器是否被复制/移走
- C++矢量复制构造函数和赋值运算符是否也复制保留空间?
- 将对象的字节复制到数组并再次复制回来是否安全
- 是否可以将不可复制的成员用作使对象不可复制的替代方法?
- 是否可以/希望创建不可复制的共享指针模拟(以启用weak_ptr跟踪/借用类型语义)?
- 如果这不是类的"复制构造函数",是否可以移动对象?
- 在这种情况下,使用 string_view 是否会导致不必要的字符串复制?
- 为什么复制构造函数不需要检查输入对象是否指向自身?
- 除了 std::vector 之外,是否有一个 std 容器不会复制和销毁作为类的元素?
- 如果我在块中编写字符串文字,是否会从数据部分复制整个字符串数据?
- 如果我也使用复制构造函数并且重载 = 运算符,我是否需要析构函数?
- 是否可以避免在以下代码中复制/移动构造函数的需要?
- std::vector 是否有用于引用的复制构造函数?
- 通过默认复制构造函数比较 C++ 字符串是否会影响性能,原因为何?
- 访问从联合与另一个成员集复制的联合中的一个成员是否未定义或未指定?
- 通过引用传递是否涉及复制地址
- 如何检查文件复制和写入是否成功
- 字符串是否在其构造函数中复制数据
- 内存C++复制是否将内存地址复制到另一个阵列