Insert vs. emplace_back 用于将新元素附加到 vector/list 如果你想要一个迭代器到新插入的元素

Insert vs. emplace_back for appending new element to vector/list if you want an iterator to the newly inserted element

我了解 insertemplace_back 对于 std::vectorstd::list 的一般差异。通常,只要我想附加一个元素,我就会使用 emplace_back 。对于某些应用程序,我需要追加元素并让迭代器指向新追加的元素。

通常,我一直在做类似的事情:

// for a vector
std::vector<T> v{store some stuff......};
v.emplace_back(new thing);
auto it = v.end() - 1; // now it points to newly inserted element

// for a list
std::list<T> l{store some stuff......};
l.emplace_back(new thing);
auto it = l.end();
--it; // now it points to newly inserted element

但我想知道使用它是否更好:

// for a vector
std::vector<T> v{store some stuff......};
auto it = v.insert(v.end(), new thing);

// for a list
std::list<T> l{store some stuff......};
auto it = l.insert(l.end(), new thing);

我认为如果 T 是 POD,差异可以忽略不计。但是如果 T 是一些非 POD,如果我最终想将迭代器追加并获取到新追加的项目,哪个会更快?根据我的理解,你必须权衡使用 emplace 的优点,它构造一个没有副本的就地对象,不像 insert,与使用 insert 的优点,这真的只是直接给我一个迭代器貌似没有别的好处。对我来说,使用 emplace 似乎会更快,因为增加迭代器的额外步骤比创建对象的副本要便宜得多?

我不知道对性能有什么影响(虽然我无法想象有什么不同)但是如果你想附加一个新元素并获得一个引用,你可以写

auto &r=v.emplace_back(a, b, c);

如果你想在上面获取一个迭代器,你可以这样写

auto it=v.emplace(cend(v), a, b, c);

据我在文档中看到的,唯一的区别是 return 类型。

使用插入与 emblace_back 相比,差异可以忽略不计。由于实现细节,列表总是会更快地插入新元素,因为插入只涉及更改几个指针,而不是偶尔重新分配和复制一个全新的动态数组。我个人会选择 emplace_back() 然后在下一行声明一个迭代器,仅仅是因为它更容易阅读和理解,如果涉及此代码的某些内容被破坏,这可以为您节省一些时间。