ARTICLE AD BOX
In the statement tsm[2] = tsm[1];, you are working with two separate SubscriptOp objects. You are not reading the value of the source SubscriptOp and assigning that value to the target SubscriptOp. You are instead assigning the source SubscriptOp itself directly to the target SubscriptOp. So, to make that work correctly, you need to define a separate operator= to handle that condition, eg:
class SubscriptOp { private: TSMap<K, V>* ts_ptr; K ts_key; public: SubscriptOp(TSMap<K, V>* _ptr, K _key) : ts_ptr(_ptr), ts_key(_key) {}; operator V() const { return ts_ptr->getValue(ts_key); } void operator=(V value) { ts_ptr->setValue(ts_key, value); } // ADD THIS! SubscriptOp& operator=(const SubscriptOp &rhs) { *this = static_cast<V>(rhs); // which is effectively doing: // (*this).operator=(rhs.operator V()); return *this; } };That being said, your code is a little over-expressive in places, and inefficient in other places.
Try something more like this:
#include <iostream> #include <mutex> #include <shared_mutex> #include <map> template <typename K, typename V> class TSMap { protected: std::map<K, V> t_map; mutable std::shared_mutex mtx; public: class SubscriptOp { private: TSMap<K, V>& ts_ref; K ts_key; public: SubscriptOp(TSMap<K, V>& _ref, const K& _key) : ts_ref(_ref), ts_key(_key) {}; operator V() const { return ts_ref.getValue(ts_key); } void operator=(const V& value) { ts_ref.setValue(ts_key, value); } SubscriptOp& operator=(const SubscriptOp& rhs) { *this = static_cast<V>(rhs); return *this; } }; V getValue(const K& key) { std::shared_lock lock(mtx); auto it = t_map.find(key); if (it == t_map.end()) throw std::invalid_argument("no what key: " + std::to_string(key)); return (*it).second; } void setValue(const K& key, const V& value) { std::shared_lock lock(mtx); t_map[key] = value; } SubscriptOp operator[](const K& key) { return SubscriptOp(*this, key); } };