Search code examples
c++boostmutexstdmapboost-mutex

How to use a boost::mutex as the mapped type in std::map?


I would like to lock the keys/index in another map like this:

std::map<int, boost::mutex> pointCloudsMutexes_;
pointCloudsMutexes_[index].lock();

However, I am getting the following error:

/usr/include/c++/4.8/bits/stl_pair.h:113: error: no matching function for call to 'boost::mutex::mutex(const boost::mutex&)'
       : first(__a), second(__b) { }
                               ^

It seems to work with std::vector, but not with std::map. What am I doing wrong?


Solution

  • In C++ before C++11, the mapped type of a std::map must be both default-constructible and copy-constructible, when calling operator[]. However, boost::mutex is explicitly designed not to be copy-constructible, because it is generally unclear what the semantics of copying a mutex should be. Due to boost::mutex not being copyable, insertion of such value using pointCloudsMutexes_[index] fails to compile.

    The best workaround is to use some shared pointer to boost::mutex as the mapped type, e.g:

    #include <boost/smart_ptr/shared_ptr.hpp>
    #include <boost/thread/mutex.hpp>
    #include <map>
    
    struct MyMutexWrapper {
        MyMutexWrapper() : ptr(new boost::mutex()) {}
        void lock() { ptr->lock(); }
        void unlock() { ptr->unlock(); }
        boost::shared_ptr<boost::mutex> ptr;
    };
    
    int main() {
        int const index = 42;
        std::map<int, MyMutexWrapper> pm;
        pm[index].lock();
    }
    

    PS: C++11 removed the requirement for the mapped type to be copy-constructible.