std::map操作的触发器 < >我想在C++中实现 MPListNe>代码> >代码> STD::MAP。因此,当在std::map中添加或更新一个键时,它应该触发一个函数或对象
它应该是:std::map操作的触发器 < >我想在C++中实现 MPListNe>代码> >代码> STD::MAP。因此,当在std::map中添加或更新一个键时,它应该触发一个函数或对象,c++,stl,C++,Stl,它应该是: 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 u
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问题)
模板
类事件图最终版
{
公众:
EventMap():数据{}
{}
//std::map::insert看起来像这样:
//标准::对插入(常数值\类型和值);
使用insert\u callback=void(常量值类型&inserted);
插入时无效(插入回调*cb)
{
在u上插入u=cb;
}
//包装插入:
无效插入(常量值\类型和值)
{
数据插入(值);
如果(在插入时)
(*插入值);
}
//TODO:为包含回调的其他方法添加类似代码
私人:
地图数据;
在_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
}
auto-on\u插入(const-auto&kv)
{
std::cout您绝对不希望在类定义中包含:public std::map
,因为这样就不可能包含所有修改map的方法
相反,您会发现客户机有一种类型,包含事件处理程序,另一种类型包装map
并将每个操作委托给它,并调用相关的处理程序函数
在map
可以工作的许多地方,您将无法使用此选项,因为要查看通过迭代器和运算符[]
对值的修改,您必须为引用成员使用代理。因此,您的迭代器和常量迭代器成员不满足转发迭代器(和BidirectionalIterator
)。因此您不满足容器
(和关联容器
)
作为不是容器
的替代方法,您可以使用std::pair
的值类型
,只需使用“擦除修改插入”进行修改即可序列。我为公然剽窃@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;
}
#包括
#包括
#包括
模板
类事件图最终版
{
公众:
EventMap():数据{}
{}
//std::map::insert看起来像这样:
//标准::对插入(常数值\类型和值);
使用insert_callback=void(const std::pair&inserted);
使用erase_callback=void(常量键和键);
插入时无效(插入回调*icb)
{
在插入时,插入=icb;
}
擦除时无效(擦除回调*ecb)
{
在欧洲央行;
}
//包装插入:
无效插入(常量标准::对和值)
{
数据插入(值);
如果(在插入时)
(*插入值);
}
//包裹擦除:
无效擦除(常量键和键)
{
数据擦除(键);
如果(打开或删除)
(*on_擦除_)(键);
}
//TODO:为包含回调的其他方法添加类似代码
私人:
地图数据;
在_insert上插入_回调*=nullptr;
擦除上的擦除回调*擦除=nullptr;
};
int main()
{
事件地图;
自动开启\u插入\u fn=[](标准::成对常数和千伏)
{
Std::你必须重载插入、更新或删除条目的功能。C++确实不是java.为什么<代码> Mpistister-<代码>继承了<代码> STD::MAP< /Calp>???@ JAKEFRIMANN,但这是<代码> MapPublisher <代码>的工作,或者是什么,而不是听者的任务?请不要从标准COTA继承它们不是虚拟的……因为你正在更改类,我必须假设你的代码是唯一一个与map
接口的代码,在map
工作的地方进行适当的调用更有意义。谢谢你。我明白了。
#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;
}