那么,是什么区别了template(c.end(),_1)和template_back(_1)呢



我认为使用template(c.end(),_1)与template_back(_1)相同但我不明白为什么语言设计者给出了两个函数而不是一个。我想我遗漏了一些信息。

那么,是什么区别了template(c.end(),_1)和template_back(_1)呢?

最大的区别是,与emplace相比,vector::emplace_backdeque::emplace_back对容器value_type的要求降低了。

仅针对vectordeque

除了来自CCD_ 8的CCD_;

emplace需要MoveInsertableMoveAssignable,而

emplace_back只需要MoveInsertable

对于包括std::allocator在内的大多数分配器,MoveInsertableMoveConstructible相同。

所以,如果你有一个类型要放入vectordeque,它是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;

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

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

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

CCD_ 27更为通用,因为它不仅仅在末尾起作用;emplace_back很方便,因为您不必编写c.end()

实施也可能带来好处;回想一下,emplace不知道您提供给它的迭代器是迭代器。

就是这样。

最新更新