C++ 使用std::map和std::list在MRU构造中实现循环依赖
我有一个映射(C++ 使用std::map和std::list在MRU构造中实现循环依赖,c++,circular-dependency,C++,Circular Dependency,我有一个映射(std::map),我想按从最近到最不最近的顺序跟踪使用的键 这是我尝试过的,但我在声明中遇到了循环依赖: typedef ... key_t; typedef struct { ... mru_list_t::iterator mru_it; } val_t; typedef std::map<key_t, val_t> foo_map_t; typedef std::list<foo_map_t::iterator> mru_lis
std::map
),我想按从最近到最不最近的顺序跟踪使用的键
这是我尝试过的,但我在声明中遇到了循环依赖:
typedef ... key_t;
typedef struct {
...
mru_list_t::iterator mru_it;
} val_t;
typedef std::map<key_t, val_t> foo_map_t;
typedef std::list<foo_map_t::iterator> mru_list_t;
typedef。。。重点;;
类型定义结构{
...
mru_list_t::迭代器mru_it;
}瓦卢特;
typedef std::map foo\u map\t;
typedef std::list mru_list_t;
更新例程似乎很简单:
foo_map_t foo_map;
mru_list_t mru_list;
void use(const key_t& key) {
// get the entry corresponding to the key
std::pair<foo_map_t::iterator, bool> r;
r = foo_map.insert(std::make_pair(key, val_t()));
foo_map_t::iterator map_it = r.first;
// the corresponding value
val_t *val = &(*map_it).second;
// did it already exist?
if (!r.second) {
// remove from the mru list
mru_list.erase(val->mru_it);
}
// push to the front of the list
mru_list.push_front(map_it);
val->mru_it = mru_list.begin();
}
foo_-map\t foo_-map;
mru清单\u t mru清单;
无效使用(常数键和键){
//获取与密钥对应的条目
std::对r;
r=foo_map.insert(std::make_pair(key,val_t());
foo\u map\u t::迭代器map\u it=r.first;
//对应的值
val_t*val=&(*映射它);
//它已经存在了吗?
如果(!r.秒){
//从mru列表中删除
mru清单。删除(val->mru清单);
}
//推到列表的前面
mru列表。向前推(映射它);
val->mru_it=mru_list.begin();
}
我该如何处理这件事?(循环依赖关系)
我知道我可以向前声明并使用指针:
typedef struct _key_t key_t;
typedef struct _val_t val_t;
typedef std::list<std::pair<key_t, val_t> *> mru_list_t;
typedef结构键;
类型定义结构值;
typedef std::list mru_list_t;
但这似乎依赖于
编辑:或者,我需要意识到这是不可能的吗?(使用未记录的功能,滚动我自己的链接列表,或者用其他非stl容器替换零件?,这取决于您使用的键类型,并且由于您使用的是单值映射,您可以尝试在列表中只存储一个
键,而不是将迭代器存储到std::map
中。因为映射每个键只有一个值,所以您仍然拥有对元素的唯一访问权,并且您摆脱了这个可怕的循环依赖性问题
代码将类似于:
typedef std::list<key_t> mru_list_t;
到
我建议您看一看哪一个是为了在同一数据段上允许多个索引而构建的(因此可以匹配多个顺序)
更具体地说,这里有一个已经存在的示例,尽管您现在可能不想查看它,并自己尝试使用该库
Boost Multi-Index的主要思想是,不要使用指向元素和多个可能不同步的相互关联结构的指针,而是将每个元素都写在一个容器单元中,该容器单元设计为与多个索引挂钩
例如,在MRU的示例中,您可以自己实现链表,方法是将每个“值”写入结构V{value\u t value;V*next;}
。而不是拥有一个列表(您必须自己进行排序),为什么不使用?在这里,您只需使用密钥,就不必担心“循环依赖关系”。@Joachim Pileborg:std::priority_queue
不可更新/重新排列。一旦将元素插入队列中,就不能删除元素,也不能更改其优先级,也不能相应地更新其在队列中的位置。与此同时,OP似乎需要能够更新优先级。通过std::priority_queue
以及软删除过时元素(将其标记为“已删除”)并插入具有新优先级的新元素,可以实现此操作。但它还远远不够完美,这很好地解决了循环依赖问题。但是,我仍然希望该语言不要求我牺牲性能以实现语义遵从性(即,如果我想要值,则需要额外的映射查找)。
mru_list.push_front(map_it);
mru_list.push_front(map_it->first);