【发布时间】:2020-09-12 14:35:09
【问题描述】:
我想看看 push_back 和 emplace_back 之间的区别,因为我在几个地方读过推荐,因为现在最好使用 emplace_back,因为“它可以做 push_back 可以做的所有事情,甚至更多”,所以我希望 ti 更有效率。但令我惊讶的是
#include <iostream>
#include <vector>
class A
{
public:
A() {std::cout << "A const" << std::endl;}
~A() {std::cout << "A dest" << std::endl;}
A(const A& a) {std::cout << "A copy const" << std::endl;}
A(A&& a) {std::cout << "A move const" << std::endl;}
A& operator=(const A& a) {std::cout << "A copy operator=" << std::endl; return *this; }
A& operator=(A&& a) {std::cout << "A move operator=" << std::endl; return *this; }
};
int main () {
std::vector<A> va;
std::cout <<"push:" << std::endl;
va.push_back(A());
std::cout <<std::endl<< "emplace:" << std::endl;
va.emplace_back(A());
std::cout <<std::endl<< "end:" << std::endl;
return 0;
}
输出是
push:
A const
A move const
A dest
emplace:
A const
A move const
A copy const
A dest
A dest
end:
A dest
A dest
emplace_back 调用 move 构造函数,然后在 push_back 仅调用一个 move const 时复制一个。我检查了 g++ (Ubuntu 7.4.0-1ubuntu1~16.04~ppa1) 7.4.0 和 online C++ shell。 我错过了什么吗?
【问题讨论】:
-
现在换个顺序,会发生什么? (也不要使用
const作为构造函数的缩写...ctor 更好,因为它不会与const冲突)。 -
当您插入第二个元素时,向量会重新分配其存储空间(因此它必须将第一个元素复制到新的存储空间)。先做
emplace_back,比较结果。 -
1.移动构造函数不是 noexcept 所以向量调用复制。 2.你重复使用相同的向量并导致重新分配。 3. 你用一个临时的 emplace_back 来调用它,这违背了目的。
-
您可以尝试另一种变体来完善这个实验,它是
emplace_back()- 请注意缺少参数 -
现在,只需调用
va.emplace_back();,无需构造一个完全无用的临时对象,用于移动构造向量中的值。