那么将emplace(c.end(),_ 1)与emplace_back(_1)区分开来的是什么?

时间:2013-02-16 21:13:19

标签: c++ c++11 std

我认为使用emplace(c.end(),_ 1)与emplace_back(_1)相同 但我不明白为什么语言设计师给出了两个功能而不是一个。 我假设我错过了一些信息。

那么将emplace(c.end(),_ 1)与emplace_back(_1)区分开来的是什么?

3 个答案:

答案 0 :(得分:5)

value_type相比,vector::emplace_backdeque::emplace_back对容器的emplace的要求减少了很大的差异。

仅针对vectordeque发言:

EmplaceConstructible之外的args;

emplace需要MoveInsertableMoveAssignable,而

emplace_back只需要MoveInsertable

对于大多数分配器,包括std::allocatorMoveInsertableMoveConstructible相同。

因此,如果您要将某个类型放入vectordeque,并且该类型为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;

然后两个例子都会编译(并运行正常)。

答案 1 :(得分:2)

根据数据结构,有可能使emplace_backemplace(c.end(), _1)更快。例如,使用std::vectoremplace_back无需检查需要移动的元素(如果有),使emplace_back稍快一些。

答案 2 :(得分:1)

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

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

实现可能也有好处 - 回想一下emplace 知道你提供给它的迭代器是 end 迭代器。 / p>

就是这样。