std::vectoremplace_back 方法是 C++11 引入的一项功能,它用于在向量的末尾直接构造新元素,而不是先构造然后复制或移动到向量中。这可以提高效率,尤其是对于那些不支持复制或效率较低的复制操作的对象。

基本用法

  • emplace_back(args...):此方法接受与元素类型构造函数相同的参数集,并在向量末尾直接构造一个新元素。这意味着它可以避免额外的复制或移动操作。

特点和注意事项

  • 直接构造:与 push_back 不同,emplace_back 直接在向量的内存空间中构造元素,这可以提高性能,特别是对于大型对象或拥有复杂移动语义的对象。
  • 参数转发:它将参数完美转发到元素的构造函数,意味着可以根据传递的参数自动选择合适的构造函数。
  • 容量变化:如果当前向量的大小等于容量,emplace_back 会引起向量的重新分配,这可能导致所有现有的迭代器、引用和指针失效。
  • 异常安全性:如果构造函数抛出异常,emplace_back 保证不会导致内存泄漏。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <vector>
#include <string>

struct MyClass {
MyClass(int x, std::string y) : num(x), str(y) {}
int num;
std::string str;
};

int main() {
std::vector<MyClass> vec;

// 直接在向量末尾构造一个 MyClass 对象
vec.emplace_back(10, "Hello");

for (const auto& item : vec) {
std::cout << item.num << ", " << item.str << std::endl;
}

return 0;
}

在这个例子中,emplace_back 被用来直接在 vector 末尾构造一个 MyClass 对象。这避免了先构造一个临时对象然后将其复制或移动到向量中的情况。

push_back的区别

push_backemplace_back 都是用于向容器(如 std::vector)中添加元素的成员函数,但它们在添加新元素时的方式和性能有所不同。

  1. push_back: 这个函数用于在容器的末尾添加一个新元素。当使用 push_back 时,它会创建该元素的副本或移动,这取决于提供的参数。如果参数是一个对象,那么 push_back 会调用该对象的拷贝构造函数或移动构造函数(如果适用)。这可能会导致额外的性能开销,特别是当对象较大或复杂时。

  2. emplace_back: 这个函数也用于在容器末尾添加新元素,但它的工作方式略有不同。emplace_back 会直接在容器的末尾构造元素,而不是首先创建一个临时对象然后拷贝或移动到容器中。它通过接受构造函数的参数来实现这一点,而不是一个已经构造好的对象。这意味着使用 emplace_back 可以减少不必要的拷贝或移动操作,从而提高效率。

简而言之,emplace_back 通常提供更好的性能,尤其是在添加复杂对象到容器中时,因为它减少了拷贝和移动的次数。然而,在某些情况下,使用 push_backemplace_back 的效果可能是相同的,尤其是对于简单或小型数据类型。


本站由 @anonymity 使用 Stellar 主题创建。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。