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成员。因此,您的iteratorconst_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

回到顶部