std :: map with iterators to std :: list from the sterators of std :: map

时间:2016-02-26 12:26:24

标签: c++ templates stl iterator

我应该如何使用迭代器将std :: list(1)声明为std :: map,它将std :: string映射到std :: list(1)的迭代器?有可能吗?

std::list<std::map<std::string, (1) ???>::iterator>;
std::map<std::string, (1) ???::iterator>;

我想要的原因 - FIFO队列能够通过密钥快速删除。

一种可能的解决方案:

struct decl_t {
    typedef std::map< std::string, decl_t > map_t;
    typedef std::list< std::pair< int, typename map_t::iterator > > list_t;

    list_t::iterator it;
};

2 个答案:

答案 0 :(得分:2)

为了能够按键删除的FIFO,我建议你使用unordered_map,因为你不需要在地图中订购。

之后,也许你可以改变你的交叉引用方案。使用字符串列表,并将字符串映射到此类列表的迭代器:

#include <unordered_map>                                                                                                                                                                                     
#include <list>
#include <string>


using map_t = unordered_map<string, list<string>::iterator>;
using list_t = list<string>;

对于在列表中有迭代器的地图中查找键的方向,您需要对名称相对于完整的迭代器到迭代器方案执行冗余哈希,但它仍然是 O(1)(预期)。相反,您的原始方案需要通过密钥删除对数操作,因此您可能仍然领先。

要插入新元素,您可以执行以下操作:

map_t map;
list_t list;

list.push_back("koko");
auto it = --list.end();
map["koko"] = it;

示例

#include <unordered_map>                                                                                                                                                                                     
#include <list>
#include <string>


using namespace std;


int main()
{
    using map_t = unordered_map<string, list<string>::iterator>;
    using list_t = list<string>;

    map_t map;
    list_t list;

    list.push_back("koko");
    auto it = --list.end();
    map["koko"] = it;
}

答案 1 :(得分:0)

这是丑陋但完整的例子

#include <cassert>
#include <iostream>
#include <list>
#include <map>
#include <string>

struct decl_t {
    typedef std::map<std::string, decl_t> map_t;
    typedef std::list<std::pair<int, typename map_t::iterator>> list_t;

    list_t::iterator it;
};

int main(int argc, const char* argv[])
{
    decl_t::map_t map;
    decl_t::list_t list;

    auto list_it = list.emplace(list.end(), 42, decl_t::map_t::iterator());
    const auto pair = std::make_pair(std::string("key"), decl_t{list_it});
    auto result = map.insert(pair);
    assert(result.second);
    auto map_it = result.first;
    list_it->second = map_it;

    std::cout << list_it->second->first << std::endl;
    std::cout << map_it->second.it->first << std::endl;
}