Map of mutex c++11

TL;DR: just use operator [] like std::map<std::string, std::mutex> map; map[filename];

Why do you need to use an std::unique_ptr in the first place?

I had the same problem when I had to create an std::map of std::mutex objects. The issue is that std::mutex is neither copyable nor movable, so I needed to construct it "in place".

I couldn't just use emplace because it doesn't work directly for default-constructed values. There is an option to use std::piecewise_construct like that:

map.emplace(std::piecewise_construct, std::make_tuple(key), std::make_tuple());

but it's IMO complicated and less readable.

My solution is much simpler - just use the operator[] - it will create the value using its default constructor and return a reference to it. Or it will just find and return a reference to the already existing item without creating a new one.

std::map<std::string, std::mutex> map;

std::mutex& GetMutexForFile(const std::string& filename)
{
    return map[filename]; // constructs it inside the map if doesn't exist
}

Replace mutexCache.insert(new std::unique_ptr<std::mutex>) with:

mutexCache.emplace(key, new std::mutex);

In C++14, you should say:

mutexCache.emplace(key, std::make_unique<std::mutex>());

The overall code is very noisy and inelegant, though. It should probably look like this:

std::string cache::get(std::string key)
{
    std::mutex * inner_mutex;

    {
        std::lock_guard<std::mutex> g_lk(gMutex);

        auto it = mutexCache.find(key);
        if (it == mutexCache.end())
        {
            it = mutexCache.emplace(key, std::make_unique<std::mutex>()).first;
        }
        inner_mutex = it->second.get();
    }

    {
        std::lock_guard<std::mutex> c_lk(*inner_mutex);
        return mainCache[key];
    }
}