emplace_back https://en.cppreference.com/w/cpp/container/vector/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)
.
Anyway 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()
大多数情况下这是正确的。至少那是意图。您确实可以在您的服务中使用它。您只需稍微调整语法即可。所以而不是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 初始化的工作方式,如果您在通用代码中使用它,您可能会错过一些构造函数。有关所有细节,请查看这篇精彩的文章:为什么聚合结构可以勇敢地初始化,但不能使用与大括号初始化中相同的参数列表来放置? https://stackoverflow.com/q/43407814/2805305