我认为使用emplace(c.end(),_ 1)与emplace_back(_1)相同 但我不明白为什么语言设计师给出了两个功能而不是一个。 我假设我错过了一些信息。
那么将emplace(c.end(),_ 1)与emplace_back(_1)区分开来的是什么?
答案 0 :(得分:5)
与value_type
相比,vector::emplace_back
和deque::emplace_back
对容器的emplace
的要求减少了很大的差异。
仅针对vector
和deque
发言:
除EmplaceConstructible
之外的args
;
emplace
需要MoveInsertable
和MoveAssignable
,而
emplace_back
只需要MoveInsertable
。
对于大多数分配器,包括std::allocator
,MoveInsertable
与MoveConstructible
相同。
因此,如果您要将某个类型放入vector
或deque
,并且该类型为MoveConstructible
,而不是MoveAssignable
,emplace_back
是你的朋友。它也可能略微更快,并且稍微更小的代码大小,但这是一个实施质量问题(标准不保证)。差异可能比您注意到的要小(除非仔细测量)。
例如,给定:
#include <vector>
struct A
{
A() = default;
A(A&&) = default;
A& operator=(A&&) = delete;
};
编译:
int main()
{
std::vector<A> v;
v.emplace_back();
}
但这不是:
int main()
{
std::vector<A> v;
v.emplace(v.end()); // error A is not MoveAssignable
}
但是,如果我改变了:
A& operator=(A&&) = delete;
为:
A& operator=(A&&) = default;
然后两个例子都会编译(并运行正常)。
答案 1 :(得分:2)
根据数据结构,有可能使emplace_back
比emplace(c.end(), _1)
更快。例如,使用std::vector
,emplace_back
无需检查需要移动的元素(如果有),使emplace_back
稍快一些。
答案 2 :(得分:1)
是的,在那种情况下,它们是等效的。
emplace
更为通用,因为它不仅仅在最后工作; emplace_back
很方便,因为您不必撰写c.end()
。
实现可能也有好处 - 回想一下 就是这样。emplace
知道你提供给它的迭代器是 end 迭代器。 / p>