std :: map操作的触发器
我想在C++中为std::map实现类似maplistner的东西。所以当在std::map中添加或更新密钥时,它应该触发一个函数或对象。std :: map操作的触发器
应该为:
class MapListener : public std::map     { 
    // ----- MapListener methods--- 
    public: 
     // Invoked when a map entry has been inserted.   
      virtual void entryInserted(); 
     // Invoked when a map entry has been updated.   
      virtual void entryUpdated(); 
     // Invoked when a map entry has been removed. 
      virtual void entryDeleted(); 
    }; 
任何帮助将不胜感激。
感谢
回答:
解决方案
(我不主张你应该这样做,只是展示了如何做到这一点,因为这听起来非常像X-Y的问题对我来说)。
template<class Key, class T, class Compare = std::less<Key>> class EventMap final 
{ 
public: 
    EventMap(): data_{} 
    {} 
    // std::map::insert looks like this: 
    // std::pair<iterator,bool> insert(const value_type& value); 
    using insert_callback = void (const value_type& inserted); 
    void on_insert(insert_callback* cb) 
    { 
     on_insert_ = cb; 
    } 
    // wrapped insert: 
    void insert(const value_type& value) 
    { 
     data_.insert(value); 
     if(on_insert_) 
      (*on_insert_)(value); 
    } 
    // TODO: add similar code for other methods w/ callbacks 
private: 
    std::map<Key, T, Compare> data_; 
    insert_callback *on_insert_ = nullptr; 
}; 
客户端回调:
auto on_insertion(const auto& kv) { 
    std::cout << "inserted: " << kv.first << ", " << kv.second << "\n"; 
} 
int main() 
{ 
    EventMap<std::string, std::string> map; 
    map.on_insert(&on_insertion); 
    map.insert({"123", 123}); // will call on_insertion after inserting 
} 
回答:
你绝对不希望在你的类定义: public std::map,因为再有就是没有保存所有的修改的方法的希望包含地图。
你会找到的是,你有一个类型的客户端,包含事件处理程序,另一种类型包装map并委托每个动作,并调用相关的处理函数。
您将无法在很多地方map将努力利用这一点,因为通过迭代器,看看修改值operator[]你不得不使用代理为您reference成员。因此,您的iterator和const_iterator成员不满足ForwardIterator(和BidirectionalIterator)。因此,您不满足Container(和AssociativeContainer)。
作为替代不是一个Container,你可以改为具有的std::pair<const Key, const Value>value_type,并且只要求修改的发生是“擦除 - 修改 - 插入”序列。
回答:
对于公然拆解@utnapistim解决方案,我表示歉意,但原文不会编译。不过我觉得很有意思,想分享工作版本:
#include <iostream> #include <string> 
#include <map> 
template<class Key, class T, class Compare = std::less<Key>> 
class EventMap final 
{ 
public: 
    EventMap() : data_{} 
    {} 
    // std::map::insert looks like this: 
    // std::pair<iterator,bool> insert(const value_type& value); 
    using insert_callback = void(const std::pair<const Key, T> &inserted); 
    using erase_callback = void(const Key &key); 
    void on_insert(insert_callback* icb) 
    { 
     on_insert_ = icb; 
    } 
    void on_erase(erase_callback *ecb) 
    { 
     on_erase_ = ecb; 
    } 
    // wrapped insert: 
    void insert(const std::pair<const Key, T>&value) 
    { 
     data_.insert(value); 
     if (on_insert_) 
      (*on_insert_)(value); 
    } 
    // wrapped erase: 
    void erase(const Key &key) 
    { 
     data_.erase(key); 
     if (on_erase_) 
      (*on_erase_)(key); 
    } 
    // TODO: add similar code for other methods w/ callbacks 
private: 
    std::map<const Key, T, Compare> data_; 
    insert_callback *on_insert_ = nullptr; 
    erase_callback *on_erase_ = nullptr; 
}; 
int main() 
{ 
    EventMap<const std::string, std::string> map; 
    auto on_insert_fn = [](std::pair<const std::string, std::string> const &kv) 
    { 
     std::cout << "inserted: " << kv.first << ", " << kv.second << "\n"; 
    }; 
    auto on_erase_fn = [](const std::string &key) 
    { 
     std::cout << "erased: " << key << "\n"; 
    }; 
    map.on_insert(on_insert_fn); 
    map.insert({ "123", "456" }); // will call on_insert_fn after inserting 
    map.insert({ "786", "101112" }); // will call on_insert_fn after inserting 
    map.on_erase(on_erase_fn); 
    map.erase("123"); // will call on_erase_fn after erasing 
    system("pause"); 
    return 0; 
} 
以上是 std :: map操作的触发器 的全部内容, 来源链接: utcz.com/qa/263701.html

