#include <iostream>
#include <map>
#include <string>
#include <algorithm>

template <class Key, class T, class Compare = std::less<Key>,
           class Allocator = std::allocator<std::pair<const Key,T> > >
class mymap: public std::map<Key, T, Compare, Allocator>
{
public:
        typedef std::map<Key, T, Compare, Allocator>    base;

        explicit mymap(const Compare& comp = Compare(), const Allocator& alloc = Allocator()): base(comp, alloc), cache_valid_(false) {}

        template <class InputIterator>
        mymap(InputIterator first, InputIterator last,
                const Compare & comp = Compare(), const Allocator & alloc = Allocator()): base(first, last, comp, alloc), cache_valid_(false) {}

        mymap(const mymap<Key,T,Compare,Allocator> & x): base(x), cache_valid_(false) {}

        mymap & operator = (mymap const & m) { base::operator = (m); cache_valid_(false); return *this; }

        ~mymap() {
                std::cout << "Hello, lamer007, i'm non virtual destructor of custom map!" << std::endl;
        }

        T & operator[] (Key const & key)
        {
                if (cache_valid_ && cached_->first == key) {
                        std::cout << "cached value for [" << key << "]" << std::endl;
                        return cached_->second;
                }

                std::cout << "real value for [" << key << "]" << std::endl;
                cached_ = base::insert(std::make_pair(key, T())).first;
                cache_valid_ = true;
                return cached_->second;
        }

        void reset_cache() { cache_valid_ = false; }

private:
        typename base::iterator cached_;
        bool                    cache_valid_;
};


int main()
{
        {
                mymap<std::string, std::string> mm;
                mm["hello"] = "world";

                if (mm["hello"] == "World" || mm["hello"] == "WORLD"
                                || mm["world"] == "hello" || mm["hello"] == "w0rld"
                                || mm["hello"] == "world")
                        std::cout << "ok" << std::endl;
                else
                        std::cout << "failed" << std::endl;

        }

        return 0;
}