1

我认为使用 emplace(c.end(),_1) 与 emplace_back(_1) 相同,但我不明白为什么语言设计者提供了两个功能而不是一个。我假设我遗漏了一些信息。

那么 emplace(c.end(),_1) 与 emplace_back(_1) 的区别是什么?

4

3 回答 3

5

最大的区别是对容器的要求value_type相对于.vector::emplace_backdeque::emplace_backemplace

vector只为deque

除了EmplaceConstructible来自args;

emplace需要MoveInsertableMoveAssignable,而

emplace_back只需要MoveInsertable.

对于大多数分配器,包括std::allocatorMoveInsertable与 相同MoveConstructible

因此,如果您有一个类型要放入vectorordeque中,它是MoveConstructible,但不是MoveAssignableemplace_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;

那么这两个例子都会编译(并运行良好)。

于 2013-02-16T21:52:33.273 回答
2

根据数据结构,可能emplace_backemplace(c.end(), _1). 例如,使用std::vector,emplace_back不必检查哪些(如果有)元素需要移动,从而emplace_back稍微快一点。

于 2013-02-16T21:21:17.267 回答
1

是的,在那种情况下它们是等价的。

emplace更通用,因为它不仅在最后起作用;emplace_back很方便,因为您不必编写c.end().

实现也可能有好处——回想一下,emplace知道您提供给它的迭代器是结束迭代器。

而已。

于 2013-02-16T21:15:51.510 回答