My goal is to write very little code and I want a custom iterator that only changes the behavior of the dereference operator*
but copies the rest of the behavior from the underlying container iterator.
The following code works but is it correct?
#include <iostream>
#include <unordered_map>
using namespace std;
template <typename K, typename V>
class KeyValueStore
{
using base_iterator = typename unordered_map<K, V>::iterator;
public:
struct iterator : public base_iterator
{
iterator(base_iterator it) : base_iterator(it)
{ }
// The custom behavior for the dereference operator.
V& operator*()
{
return base_iterator::operator*().second;
}
};
V& get(const K& key)
{
return store.at(key);
}
void put(K key, V value)
{
store[key] = value;
}
iterator begin() { return iterator {store.begin()}; }
iterator end() { return iterator {store.end()}; }
private:
unordered_map<K, V> store;
};
int main()
{
KeyValueStore<string, int> store;
store.put("aa", 5);
store.put("vf", 4);
for (auto item : store)
cout << item << endl;
return 0;
}
transform_iterator
that gives.second
. But I think you are better off just using a range adaptor, specifically map_values when you write your loop. \$\endgroup\$