c++ 11 emplace

emplace, 安放

C++11 大部分stl容器新提供的一个新的插入方式,根据容器的特性,可能有

emplace
emplace_back
emplace_front

区别于已有的insert push等,emplace可避免不必要的中间临时对象产生,提升性能。

参考std::set的emplace说明:

template <class... Args>
  pair<iterator,bool> emplace (Args&&... args);

Construct and insert element

Inserts a new element in the set, if unique. This new element is constructed in place using args as the arguments for its construction.
The insertion only takes place if no other element in the container is equivalent to the one being emplaced (elements in a set container are unique).
If inserted, this effectively increases the container size by one.
Internally, set containers keep all their elements sorted following the criterion specified by its comparison object. The element is always inserted in its respective position following this ordering.
The element is constructed in-place by calling allocator_traits::construct with args forwarded.
A similar member function exists, insert, which either copies or moves existing objects into the container.

1. 插入时就地构造.

2. 插入后容器size相应增加

例:

class CItem
{
public:
    CItem(int n):m_Id(n){
        std::cout<<"construct "<< m_Id << std::endl;
    }
       
    bool operator< (const CItem &a) const  
    {   
        return a.m_Id<m_Id;  
    }  
    
    CItem(const CItem& a){
        m_Id = a.m_Id;
        std::cout<<"copy construct "<< m_Id << std::endl;
    }

    int m_Id;
};

int main()
{
    std::set<CItem> set_tmp;
    
    set_tmp.insert(CItem(1));
    set_tmp.insert(CItem(2));
    set_tmp.insert(CItem(2));
    
    set_tmp.emplace(3);
    set_tmp.emplace(3);
    return 0;
}
construct 1
copy construct 1
construct 2
copy construct 2
construct 2
construct 3
construct 3

可以看到原来的insert会多一次拷贝构造,emplace则不会

 

附上set的源码:

先__construct_node构造一个对象,指针放入__h, 一个unique_ptr (__node_holder)中,如果没找到,则把指针insert,__inserted=true,unique_ptr释放指针,如果找到了,则不插入,内存由unique_ptr析构时处理。

template <class _Tp, class _Compare, class _Allocator>
template <class... _Args>
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
__tree<_Tp, _Compare, _Allocator>::__emplace_unique_impl(_Args&&... __args)
{
    __node_holder __h = __construct_node(_VSTD::forward<_Args>(__args)...);
    __parent_pointer __parent;
    __node_base_pointer& __child = __find_equal(__parent, __h->__value_);
    __node_pointer __r = static_cast<__node_pointer>(__child);
    bool __inserted = false;
    if (__child == nullptr)
    {
        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__h.get()));
        __r = __h.release();
        __inserted = true;
    }
    return pair<iterator, bool>(iterator(__r), __inserted);
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值