Ottenere indice numerico da Boost multi-index iteratore
-
26-09-2019 - |
Domanda
Sto memorizzare un mucchio delle seguenti
struct Article {
std::string title;
unsigned db_id; // id field in MediaWiki database dump
};
in contenitore Boost.MultiIndex, definito come
typedef boost::multi_index_container<
Article,
indexed_by<
random_access<>,
hashed_unique<tag<by_db_id>,
member<Article, unsigned, &Article::db_id> >,
hashed_unique<tag<by_title>,
member<Article, std::string, &Article::title> >
>
> ArticleSet;
Ora ho due iteratori, uno da index<by_title>
e uno da index<by_id>
. Qual è il modo più semplice per trasformare questi per gli indici nella parte ad accesso casuale del contenitore, senza aggiungere un membro di dati per struct Article
?
Soluzione
Ogni supporti indice generazione di un iteratore per valore utilizzando iterator_to . Se si dispone già di un iteratore al valore nominale in un indice, si potrebbe usare questo per convertire in un iteratore in un altro indice.
iterator iterator_to(const value_type& x);
const_iterator iterator_to(const value_type& x)const;
Per la conversione di indicizzare si può probabilmente seguire il modello in random_access_index.hpp
:
iterator erase(iterator first,iterator last)
{
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
difference_type n=last-first;
relocate(end(),first,last);
while(n--)pop_back();
return last;
}
Altri suggerimenti
iterator_to
IS una relativamente nuova funzione Boost (è lì da 1.35). Si aggiunge un po 'di zucchero di sintassi quando si utilizza con indice di default. Per le versioni precedenti di aumentare la funzione project
è l'unica scelta. È possibile utilizzare project
come segue:
ArticleSet x;
// consider we've found something using `by_db_id` index
ArticleSet::index_const_iterator<by_db_id>::type it =
x.get<by_db_id>().find( SOME_ID );
// convert to default index ( `random_access<>` )
ArticleSet::const_iterator it1 = x.project<0>( it );
// iterator_to looks like:
ArticleSet::const_iterator it11 = x.iterator_to( *it );
// convert to index tagged with `by_title` tag
ArticleSet::index_const_iterator<by_title>::type it2 = x.project<by_title>( it );
// iterator_to doen't look better in this case:
ArticleSet::index_const_iterator<by_title>::type it2 = x.get<by_title>().iterator_to( *it );
// etc.