Obtenez index numérique de multi-index Boost iterator
-
26-09-2019 - |
Question
Je suis un tas de stockage des éléments suivants
struct Article {
std::string title;
unsigned db_id; // id field in MediaWiki database dump
};
dans un récipient Boost.MultiIndex, défini comme étant
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;
Maintenant, j'ai deux itérateurs, l'un de index<by_title>
et un de index<by_id>
. Quelle est la meilleure façon de les transformer pour les index dans la partie d'accès aléatoire du conteneur, sans ajouter un membre de données à struct Article
?
La solution
Chaque indice supports génération d'un itérateur par valeur en utilisant iterator_to . Si vous avez déjà un itérateur à la valeur cible dans un index, vous pouvez l'utiliser pour convertir un itérateur dans un autre indice.
iterator iterator_to(const value_type& x);
const_iterator iterator_to(const value_type& x)const;
Pour la conversion à l'index, vous pouvez probablement suivre le modèle 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;
}
Autres conseils
iterator_to
une fonction relativement nouvelle dans Boost (il est là depuis 1.35). Il ajoute un peu de sucre de syntaxe lors de l'utilisation avec l'index par défaut. Pour les versions plus anciennes de la fonction Boost project
est le seul choix. Vous pouvez utiliser project
comme suit:
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.