C++ std::vector 的 emplace_back 能否完全取代 push_back

区别:

push_back:先在调用处构造一次 class,传递进 push_back 内后再进行拷贝到缓冲区。

emplace_back:在内部直接将构造 class 的参数转发构造到缓冲区。

如果以上说法不好理解,那么用代码来表示。

// 该 Class 支持隐式构造
class Class
{
public:
	Class(INT a) : _a(a) {}

	INT _a;
};

vector<Class> v;

// A
v.push_back(10);
// B
v.push_back(Class(10));

// C
v.emplace_back(10);
// D
v.emplace_back(Class(10));

其中:

A 和 B 是等效的。

C 和 D 不等效,且 C 比 D 快。

可见 push_back 比 emplace_back 多了一次拷贝操作。

emplace_back 的效率比 push_back 高。

那么问题来了,emplace_back 能否完全取代 push_back?

答案是:在大部分情况下是可以的。

那么小部分情况指的是什么呢?

来看例子

// 假定下面使用的 unique_ptr 支持隐式构造

vector<unique_ptr<INT>> v;

v.push_back(new INT(10));
v.emplace_back(new INT(10));

如果对该 vector 的本次操作需要 resize,且 resize 抛出了一个异常。

在这种情况下,push_back 是绝对安全的,而 emplace_back 则有可能发生内存泄露。

因为使用 push_back,在抛出异常前,unique_ptr 已经构造成功,可以正常释放内存。

但是如果使用 emplace_back,在抛出异常前,uniquer_ptr 还未进行构造,这里就只是单纯的一个指针,不会被自动释放。

参考资料:

https://blog.csdn.net/xiaolewennofollow/article/details/52559364

https://stackoverflow.com/questions/22080290/are-there-any-cases-where-it-is-incorrect-to-replace-push-back-with-emplace-back

如文章内有任何不正之处,欢迎在评论区指出。

猜你喜欢

转载自blog.csdn.net/u012088909/article/details/105309570