如何自己写vector-利用可变参模板+引用折叠,同时实现空间配置器

 0708——学习笔记

using namespace std;

// 实现容器的空间配置器:四个方法(假设创建对象Car)
template <typename T>
struct  MyAllocator {
    // allocate:申请内存
    // deallocate:释放内存
    // construct:构造函数
    // destory:析构函数
    T* allocate(size_t size) {
        return (T *)malloc(sizeof(T) * size);
    }

    //
    template<typename... Types>
    void construct(T* ptr, Types... args) {
        // args只是一个参数,且是Car对象,T也是Car对象
        // new (ptr) T(args...); // 所有参数进行展开
        new (ptr) T(forward<Types>(args)...); // 增加左右值
    }
};

// 定义自己的vector
template<typename T, typename Allo = MyAllocator<T>>
class vector {
public:
    // 默认构造
    vector():vec_(nullptr), size_(0), idx_(0) {}

    // 预留内存空间
    void reverse(size_t size) {
        // 使用new,不仅会开辟内存,还会构造,交给Allo
        vec_ = allocator_.allocate(size);
        size_ = size;
    }

    // push_back
    void push_back(const T& val) {
        allocator_.construct(vec_ + idx_, val); // 在指针加偏移处,创建一个值为val的对象
        idx_++;
    }

    void push_back(const T&& val) { // 右值引用(右值引用变量)
        // 此时val是有名字、有内存,本身是左值
        // allocator_.construct(vec_ + idx_, val); // 如果直接传val,是左值,调用左值引用
        allocator_.construct(vec_ + idx_,  move(val)); // 利用move,进行资源转移
        idx_++;
    }

    // 两个push_back也可以用可变参(此时只有一个参数,也就不用了)+引用折叠
    template<typename Type>
    void push_back(Type&& val) {
        allocator_.construct(vec_ + idx_,  forward<Type>(val)); // 利用move就全是右值
        idx_++;
    }

    // 重点:利用可变参模板 + 引用折叠,实现
    // emplace 不需要提前创建对象,直接利用参数
    template<typename... Types> // ... 代表定义了很多个模板参数
    void emplace_back(Types&&... args) {
        // ... 可以传多个参数,底层要有适配的函数
        // && 引用折叠:假设一个类为Car (根据实参推导出形参是左值引用还是右值引用)
        //           传入左值:Car类型推导。Types如果是Car,变成Car&&,变成右值——矛盾
        //                   Car类型推导。Types是Car&,变成Car& &&,引用折叠——Car&
        //           传入右值:Car类型推导。Types是Car,变成Car&&,变成右值

        // 不管是左值引用变量还是右值引用变量,本身是个左值。
        // allocator_.construct(vec_+idx_, args...); // 传递进去全是左值

        // 传递过程保持args的引用类型是左/右值 —— 完美转发
        allocator_.construct(vec_+idx_, forward<Types>(args)...);
        idx_++;
    }
private:
    T* vec_; // 指向内存
    int size_; // 长度
    int idx_; // 索引
    Allo allocator_; // 构造器
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值