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中使用它。你只需要稍微调整一下语法。所以你可以用emplace_back(1, 2)代替push_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 初始化的工作方式,如果您在通用代码中使用它,您可能会错过一些构造函数。有关所有细节,请查看这篇精彩的帖子:Why can an aggreggate struct be brace-initialized, but not emplaced using the same list of arguments as in the brace initialization?