emplace_back底层实现代码
时间: 2023-10-14 18:18:59 浏览: 47
`emplace_back()` 是 C++11 中新增的一个函数,它可以在容器的末尾直接构造一个元素,而不需要像 `push_back()` 那样先构造一个临时对象再拷贝或移动到容器中。
下面是 `emplace_back()` 的底层实现代码示例:
```cpp
template <class... Args>
void vector<T>::emplace_back(Args&&... args) {
if (size_ == capacity_) {
reserve(capacity_ == 0 ? 1 : capacity_ * 2);
}
::new (data_ + size_) T(std::forward<Args>(args)...);
++size_;
}
```
这里使用了可变参数模板 `class... Args`,接受任意数量、任意类型的参数。在函数内部,首先检查容器是否已满,如果已满则进行扩容操作;然后在容器的末尾直接使用定位 new 构造一个新元素,其中 `std::forward<Args>(args)...` 是将传入的参数以右值引用的方式转发给元素的构造函数。最后更新容器的大小。
需要注意的是,`emplace_back()` 不会检查索引越界的情况,因此调用时需要确保容器有足够的空间,并且参数类型与元素类型匹配。
相关问题
emplace_back底层原理
emplace_back是STL中vector容器提供的一个成员函数,用于在vector的末尾添加一个元素。与push_back相比,emplace_back可以直接在容器内部构造对象,避免了额外的拷贝操作,提高了效率。
emplace_back底层原理如下:
1. 首先,vector会检查当前内存空间是否足够容纳新元素。如果空间不足,vector会重新分配一块更大的内存,并将原有元素移动到新的内存中。
2. 然后,vector会在新的内存中直接构造一个新元素。这个过程调用了元素类型的构造函数,将参数传递给构造函数。
3. 最后,vector会更新自身内部状态,包括size和end指针等。
总之,emplace_back底层原理是直接在原有内存上构造新元素,避免了额外的拷贝操作。
emplace_back和push_back
emplace_back和push_back都是vector容器的成员函数,用于在容器的末尾添加元素。但是它们有一些不同之处。
push_back需要传入一个具体的元素,而emplace_back可以直接传入构造该元素所需的参数,然后容器会在内部自行构造元素。这意味着,如果添加的是一个较大的对象,使用emplace_back可以避免不必要的复制或移动操作,减少开销。同时,emplace_back也有更好的性能优化,因为它不需要调用复制构造函数或移动构造函数。
例如,假设存在一个名为Student的类,其构造函数需要传入一个string类型的学生姓名和一个int类型的学生年龄。如果想要向一个vector<Student>容器中添加一个学生,可以这样写:
```
std::vector<Student> students;
// push_back方式
Student s1("Tom", 18);
students.push_back(s1);
// emplace_back方式
students.emplace_back("Tom", 18);
```
可以看到,使用emplace_back的语法更加简洁。但是需要注意的是,由于emplace_back使用了变长模板实现,所以要保证传入的参数类型正确,并且构造函数的参数列表应该与传入的参数一一对应。
在总体上,emplace_back是更加灵活、性能更好的选择,但是如果只需要向容器中添加简单类型的元素,使用push_back就足够了。