本文主要是介绍STL中uninitialized_copy、uninitialized_fill、uninitialized_fill_n剖析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
什么是POD类型?
1、 所有标量类型(基本类型和指针类型)、POD结构类型、POD联合类型、以及这几种类型的数组、const/volatile修饰的版本都是POD类型。
2、 POD结构/联合类型:一个聚合体(包括class),它的非static成员都不是pointer to class member、pointer to class member function、非POD结构、非POD联合,以及这些类型的数组、引用、const/volatile修饰的版本;并且,此聚合体不能有用户自定义的构造函数、析构函数、拷贝构造函数.3、 POD类型可以具有static成员、成员typedef、嵌套struct/class定义和 成员函数/方法。
以下内容摘自侯捷的《STL源码剖析》
1、uninitialized_copy
C++ 标准规格书要求 uninitialized_copy() 具有 "commit or rollback" 语意, 意思是要不就「建构出所有必要元素」,要不就(当有任何㆒个 copy constructor 失败时)「不建构任何东西」。
/*参数说明:1.迭代器first指向欲初始化空间的起始处2.迭代器last指向输入端的结束位置(前闭后开区间)3.迭代器result指向输出端(欲初始化空间)的起始处
*/
template <class InputIterator ,class ForwardIterator>
inline ForwardIterator uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result)
{return __uninitialized_copy(first,last,result,value_type(result));
}template <class InputIterator ,class ForwardIterator,class T>
inline ForwardIterator __uninitialized_copy(InputIterator first,InputIterator last,ForwardIterator result,T*)
{typedef typename __type_traits<T>::is_POD_type is_POD;return __uninitialized_copy_aux(first,last,result,is_POD());
}template <class InputIterator ,class ForwardIterator,class T>
inline ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,__true_type)
{return copy(first,last,result);
}template <class InputIterator ,class ForwardIterator,class T>
ForwardIterator __uninitialized_copy_aux(InputIterator first,InputIterator last,ForwardIterator result,__false_type)
{ForwardIterator cur = first;for (;first != last;++first,++cur){construct(&*cur,*first);}return cur;
}//针对char*和wchar_t*两种类型,以最具效率的memmove来执行赋值行为
inline char* uninitialized_copy(const char* first,const char* last,char* result)
{memmove(result,first,last-first);return result + (last - first);
}inline wchar_t* uninitialized_copy(const wchar_t* first,const wchar_t* last,wchar_t* result)
{memmove(result,first,sizeof(wchar_t) * (last - first));return result + (last - first);
}
2、uninitialized_fill
uninitialized_fill()也能够使我们将记忆体配置与物件的建构行为分离开来。 如果 [first,last) 范 围内的每个迭代器都指向未初 始化的内存 ,那么 uninitialized_fill() 会在该范围内产生x(上式第三参数)的复制品。换句话说 uninitialized_fill()会针对操作范围内的每个迭代器 i , 呼叫 construct(&*i, x),在 i 所指之处产生 x 的复制品。
和 uninitialized_copy() 一样,uninitialized_fill() 必须具备 "commit or rollback" 语意,换句话说它要不就产生出所有必要元素,要不就不产生任何元素。 如果有任何一个 copy constructor 丢出异常(exception)uninitialized_fill() 必须能够将已产生之所有元素解构掉。
/*参数说明:1.迭代器first指向欲初始化空间的起始处2.迭代器last指向输入端的结束位置(前闭后开区间)3.x表示初值
*/
template <class ForwardIterator,class T>
inline void uninitialized_fill(ForwardIterator first,ForwardIterator last,const T& x)
{__uninitialized_fill(first,last,x,value_type(first));
}template <class ForwardIterator,class T,class T1>
inline void __uninitialized_fill(ForwardIterator first,ForwardIterator last,const T& x,T1*)
{typedef typename __type_traits<T1>::is_POD_type is_POD;__uninitialized_fill_aux(first,last,x,is_POD());
}template <class ForwardIterator,class T>
inline void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,__true_type)
{fill(first,last,x);
}template <class ForwardIterator,class T>
void __uninitialized_fill_aux(ForwardIterator first,ForwardIterator last,const T& x,__false_type)
{ForwardIterator cur = first;for (;cur != last;++cur){construct(&*cur,x); // 必须一个一个元素地建构,无法批量进行}return cur;
}
3、uninitialized_fill_n
uninitialized_fill_n() 能够使我们将内存配置与对象建构行为分离开来。 它会为指定范围内的所有元素设定相同的初值。如果 [first, first+n) 范围内的每一个迭代器都指向未初始化的内存,那么 uninitialized_fill_n() 会呼叫 copy constructor,在该范围内产生 x(上式 第三参数)的复制品。也就是说面对 [first,first+n) 范围内的每个迭代器 i, uninitialized_fill_n() 会呼叫 construct(&*i, x),在对应位置处产生 x 的 复制品。
uninitialized_fill_n() 也具有 "commit or rollback" 语意:要不就产生所有必 要的元素,否则就不产生任 何元素。如果任何一个 copy constructor 丢出异常 (exception),uninitialized_fill_n() 必须解构已产生的所有元素。
/*参数说明:1.迭代器first指向欲初始化空间的起始处2.n表示欲初始化空间的大小3.x表示初值
*/
template <class ForwardIterator,class size,class T>
inline ForwardIterator uninitialized_fill_n(ForwardIterator first,size n,const T& x)
{// 利用value_type取出first的value typereturn __uninitialized_fill_n(first,n,x,value_type(first));
}template <class ForwardIterator,class size,class T,class T1>
inline ForwardIterator __uninitialized_fill_n(ForwardIterator first,size n,const T& x,T1*)
{typedef typename __type_traits<T1>::is_POD_type is_POD;return __uninitialized_fill_n_aux(first,n,x,is_POD());
}//如果是POD类型,籍由函数模板的自变量推导机制得到
template <class ForwardIterator,class size,class T>
ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first,size n,const T& x,__true_type)
{return fill_n(first,n,x);
}// 如果不是POD类型
ForwardIterator __uninitialized_fill_n_aux(ForwardIterator first,size n,const T& x,__false_type)
{ForwardIterator cur = first;for (;n>0;--n,++cur){construct(&*cur,x);}return cur;
}
4、补充construct实现
void construct(pointer p,const T& value)
{_construct(p,value);
}template <class T1,class T2>
inline void _construct(T1 *p,const T2& value)
{new(p) T1(value); // placement new
}
这篇关于STL中uninitialized_copy、uninitialized_fill、uninitialized_fill_n剖析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!