push_back(std::move(string))与emplace_back(string)

push_back(std::move())与emplace_back()

今天在写一个拆分有分隔符的字符串的方法时,在最后向vector中添加string的时候突然有个问题,push_back(std::move(string))与emplace_back(string)应该用哪一个

在C++中,性能消耗是复制大于移动大于构造。

这是因为:

  • 复制(Copy)操作会创建对象的一个完整副本,这涉及到分配新的内存和复制现有对象的数据,这是三者中最耗费资源的操作。
  • 移动(Move)操作则是将一个对象的资源转移到另一个对象,这通常只涉及到修改指针或其他简单的内部状态,而不是复制整个数据,因此比复制要快。
  • 构造(Construct)操作直接在预分配的内存空间中创建对象,通常是最高效的,因为它避免了不必要的内存分配和数据复制。
    因此,当可能的时候,优先使用构造器(如emplace_back)来减少性能消耗。吗?

push_back() & emplace_back()

先来看看两者的区别,以下是push_back的简单版本,总体,一个复制版本,一个移动版本

void pushback(const T& value)
	{
		if (m_Size >= m_Capacity)
			ReAlloca(m_Capacity + m_Capacity / 2);
		m_Data[m_Size] = value;
		m_Size++;
	}
	
	void pushback(T&& value)
	{
		if (m_Size >= m_Capacity)
			ReAlloca(m_Capacity + m_Capacity / 2);
		m_Data[m_Size] =std::move(value);
		m_Size++;
	}

而emplace_back用到了完美转发和placement new,emplace_back的设计目的是在容器的内存空间中直接构造对象,这意味着emplace_back可以直接使用构造函数的参数,在容器的末尾就地构造新元素。

当你调用emplace_back时,它会将参数完美转发(perfect forwarding)到元素的构造函数,允许直接在容器的内存中构造对象。这避免了创建临时对象和额外的移动或复制操作,因此通常比push_back更高效。

template<typename...Args>
	T& emplaceback(Args&&...args)
	{
		if (m_Size >= m_Capacity)
			ReAlloca(m_Capacity + m_Capacity / 2);

		m_Data[m_Size] = T(std::forward<Args>(args)...);
		new(&m_Data[m_Size]) T(std::forward<Args>(args)...);
		return m_Data[m_Size++];
	}

在大多数情况下,直接构造对象的确比移动对象要高效。但是,这里的关键点在于emplace_back和push_back(std::move())之间的选择取决于上下文和对象的状态。

已经创建了一个string对象。在这种情况下,使用push_back(std::move(string))是合适的,因为:

已经拥有一个完整的string对象,并且在添加到vector之后不再需要它。
使用std::move可以避免复制,因为它将string对象的所有权移动到vector中,而不是创建一个新的副本。
另一方面,emplace_back更适合于直接使用构造函数参数来构造新元素的场景。如果您的场景是从一组参数开始,直接在vector中构造一个新对象,那么emplace_back将是更优的选择,因为它可以避免任何复制或移动操作。

push_back(std::move(string))可以减少不必要的性能开销。这并不意味着emplace_back不高效,而是在这种特定情况下,push_back(std::move(string))更符合您的需求。如果是从一开始就在vector中构造新元素,那么emplace_back将是更合适的选择。

总结一下:

  • 如果你想要添加一个已经存在的对象,并且想要避免复制,那么使用push_back(std::move(string))是合适的。
  • 如果你想要直接在vector中构造一个新元素,那么使用emplace_back并传递构造新元素所需的参数是更好的选择。
  • 15
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
vector的push_back和emplace_back都是向容器中添加元素的方法。它们的作用是相同的,都可以将元素添加到vector的末尾。 区别在于使用push_back时,需要传入一个已经存在的元素或临时创建的元素,而使用emplace_back时,可以直接传入构造该元素所需的参数。也就是说,emplace_back可以避免额外的复制和移动操作,因为它可以在容器内直接构造元素。 因此,如果要向vector中添加已经存在的元素或临时创建的元素,可以使用push_back;如果要向vector中添加新元素并避免额外的复制和移动操作,可以使用emplace_back。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [说说vector的emplace_back和push_back](https://blog.csdn.net/iaibeyond/article/details/119153008)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [C++ 中”emplace_back” 与 “push_back” 的区别](https://download.csdn.net/download/weixin_38548704/13997185)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值