I'm basically trying to create a thread-safe wrapper class for std::map.
As I'm coming from C, I have quite a hard time figuring out all the nuances of C++.
I'm trying to overwrite the [] operator to take std::string arguments to just pass it to my std::map member.
By the reference of std::map::operator[] this should work fine: 
T& operator[]( const Key& key );
Here is my class:
thread_map.hpp
#ifndef THREAD_MAP_H
#define THREAD_MAP_H
#include <map>
#include <functional>
#include <mutex>
template <class T>class Thread_map
{
private:
    std::map<std::string, T> map;
    std::mutex map_mutex;
public:
    ~Thread_map();
    T& at(size_t pos);
    T& operator[](std::string &key);
    size_t size() const;
    bool empty() const;
    void clear();
    void insert(std::pair<std::string, T> pair);
    T& erase(const std::string &key);
    bool for_each(std::function<bool (Thread_map, std::string&, T&)> fun);
};
template<class T> Thread_map<T>::~Thread_map()
{
    this->map.clear();
}
template<class T> T& Thread_map<T>::at(size_t pos)
{
    T *value;
    this->map_mutex.lock();
    value = this->map.at(pos);
    this->map_mutex.unlock();
    return value;
}
template<class T> T& Thread_map<T>::operator[](std::string &key)
{
    this->map_mutex.lock();
    T &value = this->map[key];
    this->map_mutex.unlock();
    return value;
}
template<class T> size_t Thread_map<T>::size() const
{
    size_t size;
    this->map_mutex.lock();
    size = this->map.size();
    this->map_mutex.unlock();
    return size;
}
template<class T> bool Thread_map<T>::empty() const
{
    bool empty; 
    this->map_mutex.lock();
    empty = this->map.empty();
    this->map_mutex.unlock();
    return empty;
}
template<class T> void Thread_map<T>::clear()
{
    this->map_mutex.lock();
    this->map.clear();
    this->map_mutex.unlock();
}
template<class T> void Thread_map<T>::insert(std::pair<std::string, T> pair)
{
    this->map_mutex.lock();
    this->map.insert(pair);
    this->map_mutex.unlock();
}
template<class T> T& Thread_map<T>::erase(const std::string &key)
{
    T *value;
    this->map_mutex.lock();
    value = this->map.erase(key);
    this->map_mutex.unlock();
    return value;
}
template<class T> bool Thread_map<T>::for_each(std::function<bool 
(Thread_map, std::string&, T&)> fun)
{
}
#endif
I put the implementation into the header file, because I heard you do that with template classes. Am I right on that? My Problem is, that when I try to call the operator
Thread_map<std::string> map;
map["mkey"] = "value";
g++ throws an invalid initialization error on map["mkey"].
As far as my understanding goes the problem is that mkey gets compiled to std::string("mkey") which is just the value, not a reference.
But why or how does the following work then?
std::map<std::string, std::string> map;
map["mkey"] = "value";
I mean I could just pass the string by value but that seems inefficient.
 
     
    