emplace_back插入元素是否始终处于容器原end()迭代器位置?
使用emplace_back()在容器尾部插入元素时,新元素是否始终位于插入前的end()位置?
当使用emplace_back()在容器尾部插入元素时,新元素是否始终保证位于容器插入前的::end()位置?
我在示例代码里,通过把插入前的end()迭代器传给新插入的entity对象,成功输出了“Hello World”,但我想知道这种行为对所有容器都有保证吗?
编辑补充:正如评论指出,std::vector这类容器插入后可能会重新分配内存,迭代器会失效,不符合这种情况。但我想知道,所有插入后能保留迭代器有效性的容器,是否都满足这个特性?
#include <cstdio> #include <functional> #include <list> struct entity { entity(std::function<void()> fn) : fn_( fn ) { } auto print() { printf("Hello World!"); } auto operator()() -> void { fn_(); } std::function<void()> fn_; }; using list_t = std::list<entity>; using iterator_t = list_t::iterator; int main() { list_t mylist; mylist.emplace_back([it = mylist.end()]{ it->print(); }); for (auto& item : mylist) { item(); } }
结论
对于**插入后能保证迭代器有效性(包括原end()迭代器)**的容器,emplace_back()插入的新元素确实会占据插入前end()迭代器指向的位置,这种行为是C++标准明确保证的。
具体分析
符合条件的容器:
std::list:链表的节点结构决定了插入操作只会修改节点指针,所有原有迭代器(包括end()哨兵迭代器)都保持有效。新插入的节点恰好位于原end()之前的位置,这也是示例能正常运行的原因。std::deque:在尾部插入元素时,除非内部缓冲区需要扩展,否则所有原有迭代器(包括end())都有效,新元素会占据原end()指向的位置。
标准规则:
根据C++标准,支持emplace_back()且插入操作不导致迭代器失效的容器,emplace_back()会在容器末尾构造新元素。容器的end()迭代器定义为指向最后一个元素的下一个位置,因此插入前的end()位置就是新元素的目标位置。插入完成后,原end()迭代器(对于链表这类容器)会指向新元素的下一个节点(即原哨兵节点),而新元素的位置正是原end()之前的位置。需要规避的容器:
std::vector、std::string:插入时若触发内存扩容,所有原有迭代器都会失效;即使未扩容,原end()迭代器也会失效,使用原end()访问新元素属于未定义行为。
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

