emplace_back vs. push_back

C++ Weekly Ep 108 and Ep 278.

C++ Weekly with Jason Turner.

C++ Weekly - Ep 108 - Understanding emplace_back

C++ Weekly - Ep 278 - emplace_back vs push_back

两期的总结。

理解 emplace_back

emplace_back 代表的是原地构造,直接上代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
struct S {
    S() {puts("S()");}
    S(const S&) {puts("S(const S&)");}
    S(S&&) {puts("S(S&&)");}
    S& operator=(const S&) {puts("S(const S&)="); return *this;}
    S& operator=(S&&) {puts("S(S&&)="); return *this;}
    ~S() {puts("~S()");}
};

int main() {
    std::vector<S> vec;
    vec.push_back(S{});
    // S() S(S&&) ~S() ~S()
    // 如果使用 emplace_back
    vec.emplace_back();
    // S() ~S()
}

观察更细致一些:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
struct S {
    S(int) {puts("S(int)");}
    ...
};

int main() {
    std::vector<S> vec;
    vec.emplace_back(5);
    // S(int) ~S()
}

emplace_back vs. push_back

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

int main() {
    std::vector<std::string> vec;
    // 如果需要构造对象,就使用 emplace_back
    vec.emplace_back(100, 'c');
    
    // 1. 给 string 分配空间 (resize)
    // 2. placement new() into new space (args...)
    
    // 如果已经有对象,那么就使用 push_back
    vec.push_back(std::string(100, 'c'));
    
    // 1. 在栈上创建临时对象
    // 2. resize vector
    // 3. std::move 来移动到新的位置
    
    // vec.emplace_back(std::string(100, 'c'));
    // emplace_back() 的错误用法
    // 先创建临时 string
    // 给 string 分配空间
    // placement new() (移动构造)
}

此外 emplace_back 是个成员函数模板

总之,push_back(std::move(obj)) 和 emplace_back 差不多

如果 push_back with copy 就很慢。

Licensed under CC BY-NC-SA 4.0
最后更新于 Feb 23, 2024 00:00 UTC