c++11总结24——emplace_back

问题引入

拿std::deque的push_back举例,其源码如下:

public: // push_* and pop_*
    void push_back(const value_type& t) {
        if (finish.cur != finish.last - 1){
            // 最后缓冲区尚有一个以上的备用空间
            construct(finish.cur, t); //直接在备用空间上构造元素
            ++finish.cur; //调整最后缓冲区的使用状态
        }
        else //最后缓冲区已无(或只剩一个)元素备用空间
            push_back_aux(t);
}

construct函数的源码如下:

template<typename T1, typename T2>
inline void construct(T1* p, const T2& value) {
	new(p)T1(value);
}

这里只探讨元素push_back进容器之后发生了什么事情,主要有三个步骤:

1)调用构造函数,构造临时对象;

2)调用拷贝构造函数,将临时对象放入容器中;

3)调用析构函数,销毁临时变量;

这个过程会造成临时变量申请资源的浪费。

emplace_back

c++11中引入了emplace_back,源码如下:

template<class... _Valty> 
decltype(auto) emplace_back(_Valty&&... _Val)   //右值引用
{	
    // insert by perfectly forwarding into element at end, provide strong guarantee
	if (_Has_unused_capacity())
	{
		return (_Emplace_back_with_unused_capacity(_STD forward<_Valty>(_Val)...));
	}
    //在调用重新构造时,将参数再完美转发出去
	_Ty& _Result = *_Emplace_reallocate(this->_Mylast(), _STD forward<_Valty>(_Val)...);
#if _HAS_CXX17
	return (_Result);
#else /* ^^^ _HAS_CXX17 ^^^ // vvv !_HAS_CXX17 vvv */
	(void)_Result;
#endif /* _HAS_CXX17 */
}

emplace_back使用了右值引用,调用了构造函数和移动构造函数,提升了效率。

关于右值引用,可以参考:c++11总结03——右值引用_却道天凉_好个秋的博客-CSDN博客

实例分析

void ThreadPool::start(int numThreads)
{
  assert(threads_.empty());
  running_ = true;
  threads_.reserve(numThreads);
  for (int i = 0; i < numThreads; ++i)
  {
    char id[32];
    snprintf(id, sizeof id, "%d", i+1);
    threads_.emplace_back(new muduo::Thread(
          std::bind(&ThreadPool::runInThread, this), name_+id));   //将thread的实例放入threads容器中 提高插入效率
    threads_[i]->start();
  }
  if (numThreads == 0 && threadInitCallback_)
  {
    threadInitCallback_();
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值