• 转发参数包的例子


    16.58 为你的StrVec类添加emplace_back函数。

    StrVec.h(注意,函数模板和模板成员函数的定义和声明要放在一起,通常都放在头文件中)

    #ifndef STRVEC_H
    #define STRVEC_H
    #include<iostream>
    #include<string>
    #include<utility>
    #include<memory>
    #include<initializer_list>
    using namespace std;
    class StrVec
    {
    friend bool operator==(const StrVec&,const StrVec&);
    friend bool operator!=(const StrVec&,const StrVec&);
    public:
        StrVec():elements(nullptr),first_free(nullptr),cap(nullptr){}
        StrVec(const StrVec&);
        StrVec& operator=(const StrVec&);
        ~StrVec() noexcept;
        //重载
        void push_back(const string&);
        void push_back(string&&);
        // emplace member covered in chapter 16
        template <class... Args> void emplace_back(Args&&...);
        size_t size() const { return first_free-elements;}
        size_t capacity() const { return cap-elements;}
        string *begin() const  {cout<<"begin"<<endl; return elements;}
        string *end() const { cout<<"end"<<endl; return first_free;}
    
        void reserve(size_t n);
        void resize(size_t n,string s=string());
    
        StrVec(initializer_list<string> il)
        {
            auto newcapacity=il.size();
            auto newdata=alloc.allocate(newcapacity);
            auto dest=newdata;
            auto elem=il.begin();
            while(elem!=il.end())
                alloc.construct(dest++,*elem);
            elements=newdata;
            first_free=cap=dest;
        }
    
        StrVec(StrVec &&s) noexcept :elements(s.elements),first_free(s.first_free),cap(s.cap)
        {
            s.elements=s.first_free=s.cap=nullptr;
        }
        StrVec& operator=(StrVec &&rhs) noexcept
        {
            if(this!=&rhs)
            {
                free();
                elements=rhs.elements;
                first_free=rhs.first_free;
                cap=rhs.cap;
                rhs.elements=rhs.first_free=rhs.cap=nullptr;
            }
            return *this;
        }
        StrVec& operator=(initializer_list<string>);
        string& operator[](size_t n)
        {
            cout<<"[]"<<endl;
            return *(elements+n);
        }
        const string& operator[](size_t n) const
        {
            cout<<"const []"<<endl;
            return elements[n];
        }
    private:
        static allocator<string> alloc;
        string *elements;
        string *first_free;
        string *cap;
        void chk_n_alloc()
        {
            if(size()==capacity()) reallocate();
        }
        pair<string*,string*> alloc_n_copy(const string*,const string*);
        void free();
        void reallocate();
    };
    bool operator==(const StrVec&,const StrVec&);
    bool operator!=(const StrVec&,const StrVec&);
    // emplace member covered in chapter 16
    template <class... Args>
    inline
    void StrVec::emplace_back(Args&&... args)
    {
        chk_n_alloc(); // reallocates the StrVec if necessary
        alloc.construct(first_free++, std::forward<Args>(args)...);
    }
    #endif // STRVEC_H

    StrVec.cpp

    #include"StrVec.h"
    #include<algorithm>
    
    allocator<string> StrVec::alloc;
    
    StrVec::StrVec(const StrVec &s)
    {
        auto newdata=alloc_n_copy(s.begin(),s.end());
        elements=newdata.first;
        first_free=newdata.second;
        cap=newdata.second;
    }
    
    StrVec& StrVec::operator=(const StrVec &s)
    {
        auto data=alloc_n_copy(s.begin(),s.end());
        free();
        elements=data.first;
        first_free=cap=data.second;
        return *this;
    }
    
    StrVec& StrVec::operator=(initializer_list<string> il)
    {
        auto data=alloc_n_copy(il.begin(),il.end());
        free();
        elements=data.first;
        first_free=cap=data.second;
        return *this;
    }
    StrVec::~StrVec() noexcept
    {
        free();
    }
    
    void StrVec::push_back(const string &s)
    {
        chk_n_alloc();
        alloc.construct(first_free++,s);
    }
    
    void StrVec::push_back(string&& s)
    {
        chk_n_alloc();
        alloc.construct(first_free++,std::move(s));
    }
    pair<string*,string*> StrVec::alloc_n_copy(const string *b, const string *e)
    {
        auto data=alloc.allocate(e-b);
        return {data,uninitialized_copy(b,e,data)};
    }
    
    void StrVec::free()
    {
        if(elements)
        {
            //for_each(elements,first_free,[](string p) { alloc.destroy(&p);});
            for_each(&elements,&first_free,[](string *p) { alloc.destroy(p);});
            //for(auto p=first_free;p!=elements;)
              //  alloc.destroy(--p);
            alloc.deallocate(elements,cap-elements);
        }
    }
    
    void StrVec::reallocate()
    {
        auto newcapacity=size()?2*size():1;
        auto newdata=alloc.allocate(newcapacity);
        auto dest=newdata;
        auto elem=elements;
       // auto last=uninitialized_copy(begin(),end(),newdata);
       //使用移动迭代器
        //auto last=uninitialized_copy(make_move_iterator(begin()),make_move_iterator(end()),newdata);
    
        for(size_t i=0;i!=size();++i)
            alloc.construct(dest++,std::move(*elem++));
        free();
        elements=newdata;
        first_free=dest;
        cap=elements+newcapacity;
    }
    
    void StrVec::reserve(size_t n)
    {
        if(capacity()<n)
            reallocate();
    }
    
    void StrVec::resize(size_t n,string s)
    {
        if(size()<n)
            push_back(s);
        else if(size()>n)
        {
            for(auto p=elements+n;p!=first_free;)
                alloc.destroy(p++);
            first_free=elements+n;
        }
    }
    bool operator==(const StrVec& lhs,const StrVec& rhs)
    {
        return lhs.elements==rhs.elements&&lhs.first_free==rhs.first_free&&lhs.cap==rhs.cap;
    }
    
    bool operator!=(const StrVec& lhs,const StrVec& rhs)
    {
        return !(lhs==rhs);
    }

    main.cpp

    #include <iostream>
    #include"StrVec.h"
    using namespace std;
    
    void print(const StrVec &svec)
    {
        cout<<"print"<<endl;
        for (auto it : svec)
            cout << it << " " ;
        cout <<endl;
    }
    int main()
    {
        StrVec vec;  // empty StrVec
        string s = "some string or another";
        vec.push_back(s);      // calls push_back(const string&)
        vec.push_back("done"); // calls push_back(string&&)
    
        // emplace member covered in chpater 16
        s = "the end";
        vec.emplace_back("10"); // adds cccccccccc as a new last element
        vec.emplace_back(s);  // uses the string copy constructor
        string s1 = "the beginning", s2 = s;
        vec.emplace_back(s1 + s2); // uses the move constructor
        print(vec);
    }

    16.61定义你自己版本的make_shared。

    #include<iostream>
    #include<memory>
    #include<string>
    using namespace std;
    
    template <typename T,typename... Args>
    shared_ptr<T>Make_shared(Args&&... args)
    {
       return make_shared<T>(std::forward<Args>(args)...);
    }
    
    int main()
    {
        auto p=Make_shared<int>(1);
        cout<<*p<<endl;
        auto pp=Make_shared<string>(10,'c');
        cout<<*pp<<endl;
    }
  • 相关阅读:
    一加5安卓P刷入twrp的recovery
    使用flask搭建微信公众号:实现签到功能
    使用flask搭建微信公众号:接收与回复消息
    Python中的单例设计模式
    Python中的异常处理
    Python面向对象 --- 新旧式类、私有方法、类属性和类方法、静态方法
    Python面向对象的三大特征 --- 封装、继承、多态
    Python面向对象 --- 类的设计和常见的内置方法
    Python中函数装饰器及练习
    Python中函数练习
  • 原文地址:https://www.cnblogs.com/wuchanming/p/3950894.html
Copyright © 2020-2023  润新知