使用std::list的splice方法实现LRU Cache
std::list splice 简介
splice函数通过重新排列链表指针,将一个std::list中的节点转移到另一个std::list中。在元素的转移过程中不会触发元素的拷贝或者移动。因此,调用splice函数之后,元素现有的引用和迭代器都不会失效。
下面是一个将listA中所有节点附加到listB的一个简单代码示例,转移的过程不会导致listA中元素的引用和迭代器失效:
// Note: c++17 required below. (For CTAD(Class template argument deducation))
std::list listA{1, 2, 3};
std::list listB{4, 5, 6};
auto it = listA.begin(); // Iterator to 1
// Append listA to listB
listB.splice(listB.end(), listA);
// All listA elements transferred to listB
std::cout << listB.size() << " " << listA.size() << std::endl; // 6 0
// Prints Below: 4 5 6 1 2 3
for (auto i : listB) {
std::cout << i << " ";
}
std::cout << std::endl;
// Iterator still valid
std::cout << *it << std::endl; // 1
当然,我们也可以在不使用splice的情况下将一个 list 中的元素转移到另一个 list 中,但是需要将原 list 中的元素删除,并在目标 list 中插入新的元素。删除和新增元素对于较小的对象(例如 int)是可以接受的,但是对于较大的对象来说,由于需要调用拷贝/移动构造和析构函数,所以成本会很高。
