类型定义相互引用的stl容器

Typedef mutually referenced stl container

本文关键字:stl 容器 引用 定义 类型      更新时间:2023-10-16

我有一个std::map和一个std::list。我希望容器中的元素具有对端容器的迭代器类型

如何定义它们的类型?

例子:

 typedef std::map<MyKeyClass, typename MyList::iterator> MyMap;
 //                                    ^ MyList not defined.
 typedef std::list<typename MyMap::iterator> MyList;

当然这两行颠倒是不行的

我也试过

 typedef std::map<MyKeyClass,
                  typename std::list<typename MyMap::iterator>::iterator> MyMap;
 typedef std::list<typename MyMap::iterator> MyList;

但这也行不通。

更新:我需要这个的原因是通过两个方面的订单来跟踪键/值对。假设有一个map<KEY,VALUE>。它是按键排序的,按键查找值很快。但我也想在加值的时候记录下这些值。我想知道哪个值最近增加的最少。为此,我使用list。我需要从map返回到列表的迭代器的原因是要擦除容器中的元素。当我通过键擦除映射中的一个元素时,也需要擦除列表中的一个元素。我还需要相反的(擦除最近的值)。我发现显式使用指针(如注释中所示)的想法不起作用,因为我实际上需要一个迭代器来擦除容器中的元素。

更新2:我问这个问题是因为我觉得我不能做这个有点奇怪。我经常使用STL容器作为基本数据结构(就像每个人一样)。例如,std::map可以用来替代具有显式结构和指针的二叉树的实现。STL容器设计得很好,我没有经历过不能使用STL容器来表达一些可以通过结构体和指针完成的结构。它们不能保证STL容器具有与结构体和指针结构相同的属性。但是,如此简单的结构,我还是觉得有点奇怪,我不能用STL容器来表达。

您可能正在寻找一个多索引容器,就像boost中发现的那样。它允许您按多个键类型对映射/集合进行排序和访问。

Boost bimap是一个类似的工具,只有两个键/索引,基本上允许您通过键和值访问映射。

你想做的是不可能的,因为它创建了一个无穷无尽的递归定义。

考虑第一个typedef中发生了什么,在第二个例子中:

typedef std::map<MyKeyClass,
    typename std::list<typename MyMap::iterator>::iterator> MyMap;

里面的MyMap会被展开,你会得到

typedef std::map<MyKeyClass,
    typename std::list<typename std::map<MyKeyClass,
        typename std::list<typename MyMap::iterator>::iterator>::iterator>::iterator> MyMap;

然后这里会有另一个MyMap要展开。现在你可以看到这是怎么回事了。您应该考虑一下您正在尝试做什么,看看是否有更好的方法来建模您的数据结构。

我想知道为什么需要循环类型的唯一原因是因为映射存储对列表的引用,而列表存储对映射的引用。换句话说,您希望在映射和列表之间共享数据。使用std::shared_ptr s的映射和std::shared_ptr s的列表,这使您可以轻松地在映射和列表之间共享元素(这是真正的数据)。

毕竟我写了下面的代码。它是由g++编译的。

struct ListEntry;
typedef std::unordered_map<MyKeyClass, typename std::list<ListEntry>::iterator> KeyMap;
struct ListEntry{
   typename KeyMap::iterator it;                                                       
};
typedef std::list<ListEntry> MyList;