Obtener índice numérico de Boost multiíndice iterador
-
26-09-2019 - |
Pregunta
Estoy almacenando un grupo de la siguiente
struct Article {
std::string title;
unsigned db_id; // id field in MediaWiki database dump
};
en un recipiente Boost.MultiIndex, define como
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;
Ahora tengo dos iteradores, uno de index<by_title>
y uno de index<by_id>
. ¿Cuál es la forma más fácil de transformar éstos a los índices en la parte de acceso aleatorio del contenedor, sin añadir un miembro de datos a struct Article
?
Solución
Cada generación soportes de índice de un iterador por valor utilizando iterator_to . Si ya tiene un iterador con el valor objetivo en un índice, se puede usar esto para convertir a un iterador en otro índice.
iterator iterator_to(const value_type& x);
const_iterator iterator_to(const value_type& x)const;
Para la conversión al índice es probable que pueda seguir el modelo de 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;
}
Otros consejos
iterator_to
una relativamente nueva función en Boost (que está ahí desde 1,35). Se añade un poco de azúcar en la sintaxis cuando se utiliza con el índice predeterminado. Para versiones anteriores de impulsar la función project
es la única elección. Puede usar project
como siguiente:
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.