【发布时间】:2020-08-07 20:39:03
【问题描述】:
对于我的任务,我使用std::list<Key> 来维护临时 LRU 缓存中元素的顺序。因此,一种常见的操作是将列表元素取出并放回列表的前面。
显然,可以先使用std::list::erase再使用std::list::push_front来实现。但是,当我想做的只是将列表节点移动到不同的位置时,我不喜欢处理内存重新分配的想法。
这正是extract 方法允许我们为std::map、std::set 等做的事情:取出一个节点,修改它然后放回去,根本不需要重新分配。
是否有合理的解释为什么std::list 缺少相同的功能,是否有一种解决方法可以用现有的类 API 来模仿它?
【问题讨论】:
-
我看不出有什么理由不进一步扩展这个想法,并拥有 intrusive containers ,例如在 STL 中提升 intrusive list 和 boost intrusive map,并制作非侵入式建立在侵入式之上。
-
This answer 是相关的。您可以使用单个命令
list.splice(list.begin(), list, iter)执行此操作,其中iter指向您要移动到开头的元素。 -
也可以查看生成的程序集,基本上只是重新分配了相关的指针:godbolt.org/z/eNAxpC。
-
@DanielLangr 这很有趣。在我的快速研究中,拼接似乎是“从一个列表到另一个列表”。不过,它确实可以在同一个列表中工作。
-
@DanielLangr,您在下面提供的 eel.is 链接显示
splice重载之一确实禁止从列表拼接到自身,即获取整个源列表内容的拼接。所以你只是部分不正确。
标签: c++ stl c++17 stdmap stdlist