仍然深入研究C++/boost,以便歡迎任何意見/反饋。固定大小的多索引多態容器提升多索引
我在玩boost :: unordered_maps,並創建了一個使用形狀的多態示例,關於我頭腦 纏繞(大部分)的時間,我偶然發現了boost multi_index的mru示例。 http://www.boost.org/doc/libs/1_46_1/libs/multi_index/example/serialization.cpp
那時我想。嗯,一個固定大小的多索引多態容器,將丟棄基於 LRU的值,這聽起來很瘋狂而不實現。
#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 <boost/shared_ptr.hpp>
#include <boost/tuple/tuple.hpp>
#include "boost/tuple/tuple_comparison.hpp"
enum shape_returns {
SHAPE_ERROR = -1,
SHAPE_OK = 0
};
// coordinates
typedef boost::tuples::tuple<int, int, int> ShapeKey;
class Shape {
public:
Shape() : pos() {}
~Shape() {}
virtual int draw() { return SHAPE_ERROR; }
ShapeKey pos;
};
typedef boost::shared_ptr<Shape> Shape_ptr;
class Circle : public Shape {
public:
Circle() {}
~Circle() {}
int radius;
virtual int draw() { /* draw stuff */ return SHAPE_OK; }
};
typedef boost::shared_ptr<Circle> Circle_ptr;
class Square : public Shape {
public:
Square() {}
~Square() {}
int len;
virtual int draw() { /* draw stuff */ return SHAPE_OK; }
};
typedef boost::shared_ptr<Square> Square_ptr;
using namespace boost::multi_index;
// multi index tags
struct seq {};
struct hash {};
class ShapesLRU {
typedef boost::multi_index::multi_index_container<
Shape_ptr,
boost::multi_index::indexed_by<
boost::multi_index::sequenced<boost::multi_index::tag<seq> >,
boost::multi_index::hashed_unique<
boost::multi_index::tag<hash>,
boost::multi_index::identity<Shape_ptr>
>
>
> shapes_list;
public:
typedef typename shapes_list::iterator iterator;
typedef typename boost::multi_index::index<shapes_list, seq>::type seq_index;
typedef typename boost::multi_index::index<shapes_list, hash>::type hashed_index;
ShapesLRU (std::size_t max) : max_shapes(max) {}
~ShapesLRU() {}
void insert(const Shape_ptr item)
{
std::pair<typename shapes_list::iterator, bool> ret = shapes.push_front(item);
if (!ret.second) {
// new item may be different
erase(item->pos);
ret = shapes.push_front(item);
} else if (shapes.size() > max_shapes) {
shapes.pop_back();
}
}
typename shapes_list::iterator begin() { return shapes.begin(); }
typename shapes_list::iterator end() { return shapes.end(); }
typename hashed_index::iterator hash_begin() { return shapes.get<hash>().begin(); }
typename hashed_index::iterator hash_end() { return shapes.get<hash>().end(); }
typename hashed_index::iterator find(const ShapeKey &key)
{
Shape_ptr tmp(new Shape());
tmp->pos = key;
// XXX why compiler error w/o "using namespace boost::multi_index"
return shapes.get<hash>().find(tmp);
}
void erase(const ShapeKey &key)
{
typename hashed_index::iterator itr = find(key);
// XXX why compiler error w/o "using namespace boost::multi_index"
shapes.get<hash>().erase(itr);
}
private:
// The multi-indexed data store
shapes_list shapes;
// The size of the data store
std::size_t max_shapes;
};
inline std::size_t
hash_value(const Shape_ptr shape)
{
std::size_t seed = 0;
boost::hash_combine(seed, shape->pos.get<0>());
boost::hash_combine(seed, shape->pos.get<1>());
boost::hash_combine(seed, shape->pos.get<2>());
return seed;
}
int
main()
{
ShapesLRU shapes(10);
Circle_ptr cptr1(new Circle());
ShapeKey pos1(1, 1, 1);
cptr1->pos = pos1;
cptr1->radius = 1;
Circle_ptr cptr2(new Circle());
ShapeKey pos2(2, 2, 2);
cptr2->radius = 2;
cptr2->pos = pos2;
shapes.insert(cptr1);
ShapesLRU::hashed_index::iterator itr = shapes.find(pos1);
return 0;
}
經過大量的工作後,我仍然留下以下問題。
- 在插入
()是有辦法從序列 迭代得到hashed_unique迭代器,所以我可以直接調用抹去?
有沒有更好的方法實現查找?如果我只用鍵就可以找到類似 的boost :: unordered_map,而不必爲查找創建一個虛擬的 形狀。
獲得<>的正確途徑是什麼(請參閱代碼XXX中的評論)我嘗試了一切,我是正確的,然後開始嘗試隨機廢話,沒有任何擺脫。
我真的想一[]操作,但我認爲這是長的路...... 形狀[cptr1-> POS] = cptr1;
如何從我的hash_index :: iterator中獲得項目(或通常意義上的這個項目),打印它當然沒有幫助...
p ITR $ 1 = {,性病::分配器>>>,升壓:: multi_index ::詳細:: bucket_array>>>,升壓:: shared_ptr的,長,提高:: shared_ptr的常量*, boost :: shared_ptr const & >> = {,std :: allocator>>>,boost :: multi_index :: detail :: bucket_array>>>,boost :: shared_ptr const *,boost :: iterator,long,boost :: shared_ptr的常量*,升壓:: shared_ptr的常量&> >> = {,性病::分配器>>>,升壓:: multi_index ::詳細:: bucket_array>>>,升壓:: shared_ptr的常量*,升壓:迭代, long,boost :: shared_ptr const *,boost :: shared_ptr const &> >> = {,std :: allocator>>>,boost :: multi_index :: detail :: bucket_array>>>,boost :: incrementable,std: :allocator> >>,boost :: multi_index :: det ail :: bucket_array>>,boost :: dereferenceable,std :: allocator>>>,boost :: multi_index :: detail :: bucket_array>>,boost :: shared_ptr const *,boost :: iterator,long,boost :: shared_ptr的常量*,升壓:: shared_ptr的常量&>>> >> = {,性病::分配器>>>,升壓:: multi_index ::詳細:: bucket_array>>>,升壓::提領,性病::分配器>>>,提振:: multi_index ::詳細:: bucket_array>>>,提高:: shared_ptr的常量*,提振::迭代器,長,提高:: shared_ptr的常量*,提高:: shared_ptr的常量&>> >> = {,std :: allocator>>>,boost :: multi_index :: detail :: bucket_array>>>,boost :: shared_ptr const *,boost :: iterator,long,boost :: shared_ptr const *,boost :: shared_ptr常量&> >> = {,長,提高:: shared_ptr的常量*,提高:: shared_ptr的常量& >> = {,長,提高:: shared_ptr的常量*,提高:: shared_ptr的常量& >> = {,長,提高:: shared_p TR常量*,升壓:: shared_ptr的常量& >> = {},},},},},},},},},節點= 0x60a010,水桶= 0x7fffffffdd88}
投影!甜心的感謝 另外我以前的散列索引是有點作弊,如果你仔細觀察我是基於ptr散列,但是,我重寫Shape_ptr hash_value返回ShapeKey的hash_value。最終它並不重要,你的解決方案非常好。我不認爲boost :: multi_index :: member可以工作,因爲存儲的項目是boost :: shared_ptr –
user442585
Shape_ptr上的索引問題是,當您想要找到具有給定鍵的元素時,您需要構造一個虛擬的Shape_ptr;在ShapeKey上建立索引可以讓你直接使用這個鍵而不用麻煩。 –