emplace_back优势在哪里?

本文通过实例代码探讨C++11中vector的push_back和emplace_back的区别。在传入自定义类型时,emplace_back直接在容器内构造对象,避免了额外的构造和析构操作,从而提供更好的性能。优势在于模板参数列表可变长和完美转发,尤其在需要多参数构造时更为明显。总结中提到,当添加自定义类型时,emplace_back的效率更高,因为它原地构造,而push_back可能涉及额外的构造和析构过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先贴上c++11升级版的push_back源码,实则是在传入右值时,调用emplace_back();
在这里插入图片描述
下面做了个测试:

class A {
public:
	A() {
		cout << "默认构造" << endl;
	}
	A(int a) {
		cout << "有参构造" << endl;
	}
	~A() {
		cout << "析构函数" << endl;
	}
	A(A&& a) {
		cout << "右值构造" << endl;
	}

	A(const A& a) {
		cout << "左值构造" << endl;
	}
};

开始测试

test1

void test1() {
	vector<A> vec;
	A a;
	cout << "______开始测试_____" << endl;
	vec.push_back(a);
	//vec.emplace_back(a);
	cout << "________________" << endl;
}

在这里插入图片描述当传入一个构造的对象时,毫无意外,push_back和emplace_back结果是一样的。

test2

void test2() {
	vector<A> vec;
	cout << "______开始测试_____" << endl;
	//vec.push_back(A{});
	vec.emplace_back(A());
	cout << "________________" << endl;
}

两种方法的结果是一样的。在这里插入图片描述

test3

void test3() {
	vector<A> vec;
	cout << "______开始测试_____" << endl;
	//vec.push_back(5);
	vec.emplace_back(5);
	cout << "________________" << endl;
}

如果是emplace:
在这里插入图片描述
如果是push_back:
在这里插入图片描述
结论:
emplace_back为什么优于push_back呢?
我觉得是因为c++11带来的几个新特性导致的:右值引用、模板参数列表可变长、右值引用的完美转发。
其中由于push_back升级了也有右值引用的版本。
因此emplace_back的优势主要在于模板参数列表可变长和完美转发。

①只有在容器中push或emplace自定义的数据类型时,才有讨论二者差别的意义。其他情况下,效果是一样的。
②在添加自定义数据时,push_back只支持一个参数的传入,而emplace_back可以支持多个。
③性能差异主要在于,在添加自定义类型时,并且只是传入1个参数时,并且需要触发自定义类型中的有参构造时,才会有区别
区别在于

  • emplace直接调用有参构造创建出临时对象,并且通过forward函数进行完美转发,原地完成添加数据。整个过程只构造一次、析构一次。
  • 而push_back需要自身先调用默认构造生成临时对象,再通过移动构造生成一个临时副本,把这个临时副本再传给emplace进行原地构造。再传给emplace_back之前,多出了一次移动构造和析构,因此一共是两次构造两次析构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值