emplace_back
将可变参数包作为参数:
template< class... Args >
reference emplace_back( Args&&... args );
当你这样调用它时:emplace_back({1, 2})
你用一个参数调用它,即{1, 2}
不能Args
推断出。那是因为语言是如何演变的。在 C++{1, 2}
中没有类型。它是一个大括号括起来的初始化列表,可用于某些类型的初始化,但都需要知道初始化的类型。这就是为什么temp_pair = {1,2};
有效,因为类型temp_pair
是已知的并且具有匹配的构造函数(int, int)
。
无论如何emplace_back
不应该那样使用,而是这样使用:
my_vec.emplace_back(1, 2);
另请注意,即使这些工作:
my_vec.emplace_back(std::pair<int, int>{1, 2});
my_vec.emplace_back(temp_pair);
它们不应该被使用。与 push_back 相比,它们没有任何优势。整点emplace_back
是避免创建一个临时的T
. 以上调用都创建了临时的std::pair<int, int>
。
但我认为你可以emplace_back()
在你拥有的任何地方
使用push_back()
在大多数情况下这是正确的。至少这是本意。你确实可以在你的cese中使用它。你只需要稍微调整一下语法。因此,push_back({1, 2})
您可以使用emplace_back(1, 2)
.
不幸的是,有一种情况你不能使用emplace_back
: 聚合。
struct Agg
{
int a, b;
};
auto test()
{
Agg a{1, 2}; // ok, aggregate initialization
std::vector<Agg> v;
v.emplace_back(1, 2); // doesn't work :(
}
除非您为Agg
. 这被认为是标准中的一个开放缺陷,但不幸的是,他们无法找到一个好的解决方案。问题在于大括号 init 初始化的工作方式,如果您在通用代码中使用它,您可能会错过一些构造函数。有关所有细节,请查看这篇精彩的帖子:为什么聚合结构可以进行大括号初始化,但不能使用与大括号初始化中相同的参数列表进行放置?