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
        uninitialized_copy() 使 我 们 能 够 将 记 忆 体 的 配 置 与 物 件 的 建 构 行 为 分 离 开 来。如果做为输出目的地的 [result, result+(last-first)) 范围内的每一个迭 代 器 都 指 向 未 初 始 化 区 域 , 则 uninitialized_copy() 会 使 用 copy 
constructor,为身为输入来源之 [first,last) 范围内的每一个对象产生一份复 制品,放进输出范围中。换句话说,针对输入范围内的每一个迭代器 i,此函式会呼叫 construct(&*(result+(i-first)),*i) ,产 生 *i 的 复制 品, 放置 于 输出范围的相对位置上。
        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 type
    return __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剖析_uninitialized copy-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值