'Erasing element from std::unordered_map by reference to element from std::list
I'm implementing my LRUCache and I have an issue with understanding the removal from std::unordered_map. All the examples in The Internet show that it's possible to remove an element from std::unordered_map using reference to element from std::list (by using std::list::back()). Why is that so? I checked out the documentation for std::unordered_map::erase() and it accepts map iterator or key as an argument, but defenitely not a reference to an element in another data structure? Is there some specific converstion or somethign about iterators I don't understand? Thank you in advance!
P.S. I would appriciate any comments on my code structure and implementation.
Here's my code for cache:
#ifndef LRUCACHE_H
#define LURCACHE_H
#include <list>
#include <unordered_map>
#include <assert.h>
#include <iostream>
template<typename T, typename KeyT = T>
class LRUCache
{
using ListItr = typename std::list<T>::iterator;
public:
LRUCache(int size) : m_size(size)
{
}
int size() const
{
return m_size;
}
bool isFull() const
{
return m_size == m_cache.size();
}
bool contains(const KeyT& key)
{
m_lookup_table.find(key) != m_lookup_table.end();
}
T get(const KeyT& key)
{
auto hit = m_lookup_table.find(key);
assert("No such element present" && hit != m_lookup_table.end());
if (hit != m_lookup_table.begin()) {
m_cache.splice(m_cache.begin(), m_cache, hit->second);
}
return *(hit->second);
}
void set(const KeyT& key, const T& value)
{
auto hit = m_lookup_table.find(key);
if (hit == m_lookup_table.end()) {
if (isFull()) {
m_lookup_table.erase(m_cache.back()); // <-- I don't understand this
m_cache.pop_back();
}
m_cache.push_front(value);
m_lookup_table[key] = m_cache.begin();
return;
}
if (hit->second != m_cache.begin()) {
m_cache.splice(m_cache.begin(), m_cache, hit->second);
}
}
void display() const
{
for (const auto& e : m_cache) {
std::cout << e << " ";
}
std::cout << std::endl;
}
private:
int m_size;
std::list<T> m_cache;
std::unordered_map<KeyT, ListItr> m_lookup_table;
};
#endif
Solution 1:[1]
There is an overload of erase that accepts Key (which in your case equals KeyT), not the iterator: https://en.cppreference.com/w/cpp/container/unordered_map/erase.
Note that back from std::list doesn't return an iterator, but the element (in your case T): https://en.cppreference.com/w/cpp/container/list/back
So my guess is that the code only compiles for your default case when KeyT = T.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
