如何实现std::vector插入?c++
How is std::vector insert implemented? C++
最近我重读了ISO c++标准,发现了一个非常有趣的注释:
注意,对于
std::vector
,std::vector<T>
的T
类型的唯一约束是T
类型必须有复制构造函数。实际上,如果插入时vector的内存已满,则分配一个新的size = 2 * oldSize
内存(这取决于实现),然后复制其中的旧元素并插入该元素。
但是等等? ?
要分配新的内存类型,我们需要这样的东西,ptr = new T[2*size];
- 这是如何做到的,因为
- 考虑到这2件事,
std::vector
如何做到这一点与"只复制构造函数?"使用了哪些实现和语言习语?
T
类型可能没有默认构造函数?然后赋值,在分配内存之后,我们必须将旧值分配给新内存,对吗?通过调用allocator函数allocate()获取原始内存,然后调用allocatorconstruct(iterator, val)通过使用位置new复制来构造一个元素,即类似于
:/* approach similar to std::uninitialized fill taken */
template<typename T, typename A >
vector<T,A>::vector( size_type n, const T& val, const A& a) : alloc( a) // copy the allocator
{
/* keep track of which elements have been constructed
* and destroy those and only those in case of exception */
v = alloc.allocate( n); // get memory for elements
iterator p; // declared before try{} so it is still valid in catch{} block
try {
iterator end = v + n;
for( p = v; p != end; ++p)
alloc.construct( p, val); /* construct elements (placement new):
e g. void construct( pointer p, const T& val)
{ ::new((void *)p) T( val); } */
last = space = p;
} catch( ...) {
for( iterator q = v; q != p; ++q)
alloc.destroy( q); /* destroy constructed elements */
alloc.deallocate( v, n); /* free memory */
throw; /* re-throw to signal constructor that failed */
}
}
在c++中,allocator用于将必须分配内存的算法实现者和容器与物理内存的细节隔离开来。
也可以采用直接使用uninitialized_fill的方法:
std::uninitialized_fill( v, v + n, val); /* copy elements with (placement new):
e g. void construct( pointer p,
const T& val)
{ ::new((void *)p) T( val); } */
这在Bjarne Stroustrup的"c++…"中有详细描述。第3版"。下面是基于此编写的示例:
作为一般规则,标准容器分开分配从初始化开始(您编写的任何容器也应该如此)。标准容器使用非常复杂的机制来允许自定义分配和初始化,但是在默认情况下,它可以归结为使用operator new
/operator delete
函数分配内存;位置new来初始化它,并显式调用析构函数来销毁对象。换句话说,而不是序列:
p = new T[n];
// ...
delete [] p;
它使用:
p = operator new( n * sizeof( T ) );
for ( int i = 0; i != n; ++ i ) {
new ( p + i ) T( otherValue );
}
// ...
for ( int i = 0; i != n; ++ i ) {
p->~T();
}
operator delete( p );
这是一个彻底的简化,以显示基本概念。在实践中,由于例外的原因,它将更加复杂)
考虑emplace_back():最有可能的是vector分配了一块新的未初始化内存,然后运行placement new来就地复制构造对象。
相关文章:
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 如何有效地在 std::vector 中插入一对?
- 为 std::vector 编写自定义插入函数
- 有没有更快的方法可以在 std::vector 中插入元素
- 在 C++ 中使用 Vector 在动态数组中插入值,循环
- 如何将 n 个连续元素插入到元素类型不可复制的 std::vector 中?
- 在设计方面:重载vector类型的类成员的插入运算符
- 如何在一对集合的向量中插入元素?vector<pair<int,set<string>>>
- C++ 如何在 std::vector 中插入一个连续的间隔范围?
- 将 2D 数组插入 std::vector 时"cannot convert from 'const GLfloat [12]' to '_Objty'"错误消息
- 有没有办法将 vector<unsigned char> 插入 postgresql 表中,具有 bytea 属性,没有 UTF8 编码错误?
- 当使用 std::vector::p ush_back 插入未知数量的元素时,是否应该在每次推送时检查 std::vec
- 如何将对象插入std::vector
- SegFault将插入std :: vector的成员函数插入std :: vector
- 我可以按值(复制)将对象从一个 std::vector 插入到另一个吗?
- vector插入对象的副本或引用
- vector插入新对象
- 如何实现std::vector插入?c++
- stl vector::插入Windows和linux中的差异
- 按字母顺序向vector插入对象