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