Implementing a custom iterator by inheriting from an existing iterator class and overriding operator* 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 &lt;iostream&gt;
#include &lt;unordered_map&gt;

using namespace std;

template &lt;typename K, typename V&gt;
class KeyValueStore
{
    using base_iterator = typename unordered_map&lt;K, V&gt;::iterator;

public:
    struct iterator : public base_iterator
    {
        iterator(base_iterator it) : base_iterator(it)
        { }

        // The custom behavior for the dereference operator.
        V&amp; operator*()
        {
            return base_iterator::operator*().second;
        }
    };

    V&amp; get(const K&amp; 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&lt;K, V&gt; store;
};


int main()
{
    KeyValueStore&lt;string, int&gt; store;
    store.put("aa", 5);
    store.put("vf", 4);

    for (auto item : store)
        cout &lt;&lt; item &lt;&lt; endl;

    return 0;
}
Use of public inheritance in this case strikes me as problematic.

Public inheritance means that a pointer/reference to an object of the derived class can be converted implicitly to a pointer/reference to the base class. Worse, it also means that an object of the derived class can be implicitly converted ("sliced") to an instance of the base class.

If that happens, you quickly run into a problematic situation: since operator * isn't defined as virtual in the base class, invoking it via a pointer/reference to base will invoke the base version of the operator. Your operator overload isn't really overriding the base class'--it's just hiding it.

This isn't saving a whole lot of work either--you're using an unordered associative container, which only provides forward iterators, so all your inheritance is saving is implementing operator++.

I suppose to be fair, I should add that people rarely pass iterators by reference, so it's not particularly likely that you'll trigger the problems outlined above. On the other hand, history teaches us that idiots can be surprising crafty in figuring out ways to shoot themselves in the feet.