2012-05-30 3 views
1

Ce code est adopté à partir de l'impulsion multi-index "MRU" exemple:stimuler l'accès aux index multiples à hashed index unique

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

J'ai le code qui fait quelque chose de similaire comme un coup de pouce :: unordered_map, mais j'aimerais vraiment ajouter la fonctionnalité mru de cet exemple.

Je voudrais que ce code fonctionne au plus près d'avoir boost :: unordered_map que possible. L'élément clé pour moi est l'opérateur [] de la carte unordered_map.

Les dernières lignes de main() sont cassées et au-dessus de chaque ligne comme un commentaire est ma question.

Merci d'avance pour toutes les réponses aux commentaires.

#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

Je doute que cela soit lié à votre problème, mais vous déclarez que votre opérateur ami prend un 'const mystruct &', mais votre définition prend un mystruct & '. – ildjarn

Répondre

2

// quel est mon type de retour?

mru.il.get<umap>(); 

Son type de retour est le type de votre index umap, qui est:

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

En C++ 11, il est plus facile avec auto:

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

// Pourquoi ça ne marche pas?

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

find() renvoie un itérateur de l'indice umap (deuxième) et le rapport ci-dessus est d'attribuer à l'itérateur du premier index. Il y a projection operations convertir un index type iterator à un autre type de iterator du même conteneur multi-index, par exemple:

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

// Pourquoi ne pas avoir un opérateur [] comme boost: unordered_map

Impossible de dire pourquoi, it just doesn't.