After learning that std::map containers are not inherently atomic and therefore not thread-safe (check out this related Stack Overflow question and usage example), I decided to create code that would allow concurrent access to the container.#ifndef MAP_GUARD_H_#define MAP_GUARD_H_/*This class was designed to make the standard map synchronized for the basic functions.The intent was for it to be filled with shared_ptr as the value in the pair.A Grand Central Dispatch serial queue is used for syncronising access to the map rather than raw mutexes.*/// A macro to disallow the copy constructor and operator= functions// This should be used in the private: declarations for a class#define DISALLOW_COPY_AND_ASSIGN(TypeName) \  TypeName(const TypeName&);               \  void operator=(const TypeName&)#include <map>#ifdef WIN32#include <xdispatch\dispatch.h>#else#include <xdispatch/dispatch.h>#endiftemplate <class K, class V>class map_guard{public:    map_guard();    ~map_guard();    void clear();    void erase(const K& key);    void insert(const K& key, const V& value);    /* Take a snopshot of map_ and fill target with it (usefull if you want to use iterators) */    void fill_map(std::map<K, V>& target) const;    V find(const K& key) const;    size_t size() const;    bool empty() const;    void swap(std::map<K, V>& map);private:    void make_swap(std::map<K, V>* map);    void get(std::map<K, V>* target) const;    void get(const K& key, V* target) const;    void get_empty(bool* empty) const;    void get_size(size_t* size) const;    std::map<K, V> map_;    xdispatch::queue* dispatch_queue_;    DISALLOW_COPY_AND_ASSIGN(map_guard);};template <class K, class V>map_guard<K, V>::map_guard() : dispatch_queue_(0){    dispatch_queue_ = new xdispatch::queue(test);}template <class K, class V>map_guard<K, V>::~map_guard(){    if(dispatch_queue_)    {        delete dispatch_queue_;        dispatch_queue_ = 0;    }}template <class K, class V>void map_guard<K, V>::clear(){    dispatch_queue_->sync(${        map_.clear();    });}template <class K, class V>void map_guard<K, V>::erase(const K& key){    dispatch_queue_->sync(${        map_.erase(key);    });}template <class K, class V>void map_guard<K, V>::insert(const K& key, const V& value){    dispatch_queue_->sync(${        map_[key] = value;    });}template <class K, class V>void map_guard<K, V>::get(std::map<K, V>* target) const{    dispatch_queue_->sync(${        target->insert(map_.begin(), map_.end());    });}template <class K, class V>void map_guard<K, V>::get(const K& key, V* target) const{    dispatch_queue_->sync(${        std::map<K, V>::const_iterator it = map_.find(key);        if(it != map_.end())        {            *target = it->second;        }    });}template <class K, class V>void map_guard<K, V>::fill_map(std::map<K, V>& target) const{    get(&target);}template <class K, class V>V map_guard<K, V>::find(const K& key) const{    V temp;    get(key, &temp);    return temp;}template <class K, class V>void map_guard<K, V>::get_size(size_t* size) const{    dispatch_queue_->sync(${        *size = map_.size();    });}template <class K, class V>size_t map_guard<K, V>::size() const{    size_t size;    get_size(&size);    return size;}template <class K, class V>void map_guard<K, V>::get_empty(bool* empty) const{    dispatch_queue_->sync(${        *empty = map_.empty();    });}template <class K, class V>bool map_guard<K, V>::empty() const{    bool empty;    get_empty(&empty);    return empty;}template <class K, class V>void map_guard<K, V>::swap(std::map<K, V>& map){    make_swap(&map);}template <class K, class V>void map_guard<K, V>::make_swap(std::map<K, V>* map){    dispatch_queue_->sync(${        map_.swap(*map);    });}#endifIs this a valid method for solving the problem? Are there other ways that may be more efficient?
Thread-safe std::map accessor
c++;multithreading;thread safety;synchronization;stl