C++11 emplace方法

        C++11引入三个新成员-emplace_frontemplaceemplace_back ,可以方便地在容器中进行构造元素的操作,用于在容器中直接构造对象,从而减少不必要的拷贝或者移动操作,提高代码效率和性能。

        这些操作分别对应push_front, insert和push_back,能够让我们把元素放置在容器头部,一个指定位置之前或容器尾部。

c.emplace_back(t)在c的尾部创建一个值为t的元素
c.emplace_front(t) 在c的头部创建一个值为t的元素
c.emplace(p,t) 在迭代器p所指向的元素之前创建一个值为t的元素,返回指定新添加元素的迭代器

#include <bits\stdc++.h>
using namespace std;

class Test
{
public:
    Test(int a){cout<<"Test(int)"<<endl;}
    Test(int a, int b) {cout<<"Test(int, int)"<<endl;}
    ~Test(){cout<<"~Test()"<<endl;}
    Test(const Test&) {cout <<"Test(const Test&)"<<endl;} //左值引用
    Test(Test&&) {cout<<"Test(Test&&)"<<endl;} //右值引用
};

int main()
{
    Test t1(10);
    vector<Test> v;
    v.reserve(100);

    cout<<"=========="<<endl;
    //直接插入两个对象 没有区别
    v.push_back(t1);
    v.emplace_back(t1);
    cout<<"=========="<<endl;
    //插入两个临时对象 也没有区别
    v.push_back(Test(20));
    v.emplace_back(Test(20));
    cout<<"=========="<<endl;
    //只需要传入参数 直接调用相应参数类型函数 构造新对象 
    //避免了额外的对象拷贝或移动操作,可以更高效地构造元素。
    v.emplace_back(20);
    v.emplace_back(30,40);
    cout<<"=========="<<endl;    
    return 0;
}

  • 当调用push或insert成员函数时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中。
  • 而当我们调用一个emplace成员函数时,则是将参数传递给元素类型的构造函数
  • emplace成员使用这些参数在容器管理的内存空间中直接构造元素

 

#include <bits\stdc++.h>
#include <iostream>
#include <vector>

using namespace std;

class Test
{
public:
    Test(int a) { cout << "Test(int)" << endl; }
    Test(int a, int b) { cout << "Test(int, int)" << endl; }
    ~Test() { cout << "~Test()" << endl; }
    Test(const Test&) { cout << "Test(const Test&)" << endl; } //左值引用
    Test(Test&&) { cout << "Test(Test&&)" << endl; } //右值引用
};

//实现容器的空间配置器
template<typename T>
struct MyAllocator
{
    // allocate deallocate 开辟内存 释放内存
    // construct destory 创建对象 销毁对象
    T* allocate(size_t size)
    {
        return (T*)malloc(size * sizeof(T)); //用 malloc 分配一块内存空间,并返回指向该内存的指针
    }
     
    template<typename... Types>
    void construct(T* ptr, Types&&... args)
    {
        // args只是一个参数,而且是个Test对象,T也是Test类型
        // 还是需要类型完美转发
        new(ptr)T(std::forward<Types>(args)...);
    }

};

//第一个参数是容器中放得内容类型  第二个参数是空间配置器类型
template<typename T, typename Alloc = MyAllocator<T>>
class vector
{
public:
    //默认构造函数
    vector() : vec_(nullptr), size_(0), idx_(0){}

    //预留空间
    void reserve(size_t size)
    {
        vec_ = allocator_.allocate(size);
        size_ = size;
    }

    //----------------------------------------------------------
    //push_back
    //void push_back(const T& val) //左值
    //{
    //    allocator_.construct(vec_ + idx_, val);
    //    idx++;
    //}
    //void push_back(T&& val)  //右值
    //{
    //    allocator_.construct(vec_ + idx_, std::move(val));
    //    idx++;
    //}
    // 
    // 引用折叠 
    template<typename Type>
    void push_back(Type&& val)
    {
        allocator_.construct(vec_ + idx_, std::forward<Type>(val));
        idx++;
    }
    //------------------------------------------------------------

    // 1.引用折叠 + 可变参数模板 
    template<typename... Types>
    void emplace_back(Types&&... args) //可接受多个数量参数
    {
        //不管是左值还是右值引用变量,本身都是个左值
        //传递的过程中要保持传递参数的类型不变  需要使用forward完美转发
        allocator_.construct(vec_ + idx_, std::forward<Types>)(args)...);
        idx_++;
    }

private:
    T* vec_;  //指向类型T的指针
    int size_;  //空间大小
    int idx_;   //当前索引位置
    Alloc allocator_;  //使用的空间配置器对象
};

int main()
{
    Test t1(10);
    vector<Test> v;
    v.reserve(100);

    cout << "==========" << endl;
    //直接插入两个对象 没有区别
    v.push_back(t1);
    v.emplace_back(t1);
    cout << "==========" << endl;
    //插入两个临时对象 也没有区别
    v.push_back(Test(20));
    v.emplace_back(Test(20));
    cout << "==========" << endl;
    //只需要传入参数 直接调用相应参数类型函数 构造新对象 
    //避免了额外的对象拷贝或移动操作,可以更高效地构造元素。
    v.emplace_back(20);
    v.emplace_back(30, 40);
    cout << "==========" << endl;

    /*
    map<int,string> m;
    m.insert(make_pair(10,"zhang san");
    m.emplace(10,"zhang san"); =>在map底层直接调用普通构造函数,生成一个pair对象即可
    */

    return 0;
}

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值