gpt4 book ai didi

c++ - C++17 和 emplace_back(...) 中的保证复制省略

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:06 26 4
gpt4 key购买 nike

emplace_back(...)是在 C++11 中引入的,以防止创建临时对象。现在使用 C++17,纯左值甚至更纯,因此它们不会再导致临时对象的创建(更多信息请参见 this question)。现在我仍然不完全理解这些变化的后果,我们是否还需要 emplace_back(...) 还是我们可以回去使用 push_back(...) 又是?

最佳答案

push_backemplace_back 成员函数都在其value_type T 的某个位置创建了一个新对象预分配缓冲区。这是由 vector 的分配器完成的,默认情况下,它使用 placement new 机制来构建(placement new 基本上只是一种在内存中指定位置构造对象的方法)。 p>

但是:

  • emplace_back 将其参数完美转发给 T 的构造函数,因此选择与这些参数最匹配的构造函数。
  • push_back(T&&) 在内部使用移动构造函数(如果存在且不抛出)来初始化新元素。此移动构造函数调用不能省略,并且始终使用。

考虑以下情况:

std::vector<std::string> v;
v.push_back(std::string("hello"));

std::string 的移动构造函数总是在此处调用,跟在从字符串字面量创建字符串对象的转换构造函数之后。在这种情况下:

v.emplace_back("hello");

没有调用移动构造函数, vector 的元素直接由 std::string 的转换构造函数初始化。


这并不一定意味着 push_back 效率较低。编译器优化可能会消除所有额外的指令,最终这两种情况可能会产生完全相同的汇编代码。只是不能保证。


顺便说一下,如果 push_back 按值传递参数 — void push_back(T param); — 那么这就是应用复制省略的情况。即,在:

v.push_back(std::string("hello"));

参数 param 将由临时的移动构造函数构造。这种移动结构将成为复制省略的候选者。但是,这种方法根本不会改变 push_back 主体中 vector 元素的强制移动构造。

关于c++ - C++17 和 emplace_back(...) 中的保证复制省略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57389600/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com