• 标准库Allocator(三)uninitialized_fill等函数的实现


    前面我们使用了uninitialized_fill,来批量初始化某一段内存。

    下面提供三个函数的实现代码,这三个代码的共同点是:

    1.遇到错误,抛出异常

    2.出现异常时,把之前构造的对象全部销毁

    所以,这三个函数要么成功,要么无任何副作用。使用异常来通知使用者,所以在catch块中,处理完异常后要将异常再次向外抛出

    #ifndef MEMORY_HPP
    #define MEMORY_HPP
    
    #include <iterator>
    
    template <typename ForwIter, typename T>
    void uninitialized_fill(ForwIter beg, ForwIter end, const T & value)
    {
        typedef typename std::iterator_traits<ForwIter>::value_type VT;
        ForwIter save(beg); //备份beg的初始值
        try
        {
            for(; beg != end ; ++beg)
            {
                new (static_cast<void *>(&*beg))VT(value);
            }
        }
        catch(...) //抛出异常
        {
            for(; save != beg; ++save)
            {
                save->~VT();    //逐个进行析构
            }
            throw; //将catch的异常再次抛出
        }
    }
    
    
    template <typename ForwIter, typename Size, typename T>
    void uninitialized_fill_n(ForwIter beg, Size num, const T & value)
    {
        typedef typename std::iterator_traits<ForwIter>::value_type VT;
        ForwIter save(beg);
        try
        {
            for(; num-- ; ++beg)
            {
                new (static_cast<void *>(&*beg))VT(value);
            }
        }
        catch(...)
        {
            for(; save != beg; ++save)
            {
                save->~VT();
            }
            throw;
        }
    }
    
    template <typename InputIter, typename ForwIter>
    void uninitialized_copy(InputIter beg, InputIter end, ForwIter dest)
    {
        typedef typename std::iterator_traits<ForwIter>::value_type VT;
        ForwIter save(dest);
        try
        {
            for(; beg != end ; ++beg, ++dest)
            {
                new (static_cast<void *>(&*dest))VT(*beg);
            }
        }
        catch(...)
        {
            for(; save != dest; ++save)
            {
                save->~VT();
            }
            throw;
        }
    }
    
    #endif /* MEMORY_HPP */

    可以使用前面的代码自行测试。

  • 相关阅读:
    GO 语言使用copy 拷贝切片的问题
    ggplot 局部放大
    R语言hist重叠图作法
    illumina SNP 芯片转基因型矩阵
    Shell 变量嵌套
    JVM指令
    VUE—CLI学习
    Gradle 项目打开自动下载Zip问题及相关配置
    MySQL8服务无法启动,服务没有报告任何错误
    SpringMVC相关
  • 原文地址:https://www.cnblogs.com/inevermore/p/4004655.html
Copyright © 2020-2023  润新知