2012-05-30 2 views
1

Этого код принимаются от повышающего мультииндекса «СРМ» пример:увеличить мульти доступа индексного хэшируются уникальный индекс

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

У меня есть код, который делает что-то подобное как бустерного :: 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; 
} 
+0

Я сомневаюсь, что это связано с вашей проблемой, но вы заявляете, что оператор вашего друга принимает 'const mystruct &', но ваше определение принимает 'mystruct &'. – ildjarn

ответ

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)); 

// Почему это не есть оператор [], как импульс: unordered_map

Не могу сказать, почему, it just doesn't.