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?

¿Fue útil?

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.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top