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

template <typename Cont>
class Localizer
{
 public:
   typedef typename Cont::key_type key_type;
   typedef typename Cont::data_type data_type;

   // Remember whether the container originally had a value with the key we
   // are going to use for the new locally set value, and if so what it was.
   Localizer (Cont &container, const key_type &key, const data_type &new_value)
      : container_(container), key_(key),
        was_here_(container.find(key) != container.end())
   {
      orig_value_ = container[key];
      container[key] = new_value;
   }

   // If there was originally a value in the container, which has been
   // temporarily replaced, then put the old value back, otherwise remove
   // the temporary value.
   ~Localizer ()
   {
      if (was_here_)
         container_[key_] = orig_value_;
      else
         container_.erase(container_.find(key_));
   }

 private:
   Cont &container_;
   key_type key_;
   data_type orig_value_;
   bool was_here_;
};

// Print out the contents of an associative container, with dashes to separate
// each container's contents.
template <typename Cont>
void
dump_assoc_container (const Cont &container)
{
   static bool first = true;
   if (first)
      first = false;
   else
      std::cout << std::string(70, '-') << std::endl;

   for (typename Cont::const_iterator it = container.begin();
        it != container.end();
        ++it)
   {
      std::cout << it->first << " => " << it->second << std::endl;
   }
}

int
main ()
{
   // Create a map with a value in, and dump it to prove the value is set.
   std::map<std::string, std::string> things;
   things["foo"] = "bar";
   dump_assoc_container(things);

   {
      // Within this scope, set a new value for the key 'foo', and dump it to
      // show that the value has been changed.
      Localizer<std::map<std::string, std::string> > tmp (things, "foo", "um");
      dump_assoc_container(things);
   }

   // Now we're out of that scope, so Localizer's destructor should have put
   // the map back as it was.
   dump_assoc_container(things);
}
