提升对散列唯一索引的多索引访问

时间:2012-05-30 04:09:18

标签: c++ boost lru boost-multi-index

此代码从boost多索引“mru”示例中采用:

http://www.boost.org/doc/libs/1_46_1/libs/multi_index/example/serialization.cpp

我的代码类似于boost :: unordered_map,但我真的想在这个例子中添加mru功能。

我想让这段代码尽可能接近boost :: unordered_map。对我来说,关键特性是unordered_map的[]运算符。

main()的最后一行被打破,每行上面都有一条评论是我的问题。

提前感谢所有答案评论。

#include <algorithm>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <iostream>

using namespace boost::multi_index;

class my_struct {
public:
    my_struct(int in_a, std::string in_b) : a(in_a), b(in_b) {}

    int a;
    std::string b;

    bool operator==(const my_struct &rhs) const
    {
        return (a == rhs.a);
    }
    bool operator!=(const my_struct &rhs) const
    {
            return !(*this == rhs);
    }

    friend std::ostream& operator<<(std::ostream &out, const my_struct&ms);
};

std::ostream& operator<<(std::ostream &out, my_struct &ms)
{
    out << ms.a << " " << ms.b << std::endl;
    return out;
}

inline std::size_t
hash_value(const my_struct &val)
{
    return boost::hash_value(val.a);
}

// tags for multi_index
struct umap {};
template <typename Item>
class mru_list
{
  typedef multi_index_container<
    Item,
    indexed_by<
      sequenced<>,
      hashed_unique<boost::multi_index::tag<umap>, identity<Item> >
    >
  > item_list;

public:

  typedef Item                         item_type;
  typedef typename item_list::iterator iterator;

  mru_list(std::size_t max_num_items_):max_num_items(max_num_items_){}

  void insert(const item_type& item)
  {
    std::pair<iterator,bool> p=il.push_front(item);

    if(!p.second){                     /* duplicate item */
      il.relocate(il.begin(),p.first); /* put in front */
    }
    else if(il.size()>max_num_items){  /* keep the length <= max_num_items */
      il.pop_back();
    }
  }

  iterator begin(){return il.begin();}
  iterator end(){return il.end();}

//private:
  item_list   il;
  std::size_t max_num_items;
};

int main()
{
    mru_list<my_struct> mru(10);
    my_struct one(1, "One");

    mru.insert(one);
    mru.insert(my_struct(2, "Two"));
    mru.insert(my_struct(3, "Three"));
    mru.insert(one);

    std::cout<<"most recently entered terms:"<<std::endl;
    for (mru_list<my_struct>::iterator itr = mru.begin(); itr != mru.end(); ++itr) {
        std::cout << itr->a << std::endl;
    }

    // what is my return type?
    mru.il.get<umap>();

    // Why doesn't this work?
    mru_list<my_struct>::iterator itr = mru.il.get<umap>().find(one);

    // Why doesn't this have a [] operator like boost:unordered_map
    mru.il.get<umap>()[1] = "foobar";

    return 0;
}

1 个答案:

答案 0 :(得分:2)

  

//我的返回类型是什么?

mru.il.get<umap>();

它的返回类型是umap索引的类型,即:

  typedef typename boost::multi_index::index<
        item_list
      , umap
      >::type hashed_index_t;

  mru_list<my_struct>::hashed_index_t& hashed_index = mru.il.get<umap>();

在C ++ 11中,使用auto

更容易
  auto& hashed_index = mru.il.get<umap>();
  

//为什么这不起作用?

mru_list<my_struct>::iterator itr = mru.il.get<umap>().find(one);

find()返回umap(第二个)索引的迭代器,上面的语句将它分配给第一个索引的迭代器。有projection operations从一个索引迭代器类型转换为同一个多索引容器的另一个迭代器类型,例如:

mru_list<my_struct>::iterator itr = project<0>(mru.il, hashed_index.find(one));
  

//为什么没有像boost:unordered_map

这样的[]运算符

不能说为什么,it just doesn't