2010-11-18 51 views
6

我存储了一堆以下获取与Boost多指标的迭代器

struct Article { 
    std::string title; 
    unsigned db_id;  // id field in MediaWiki database dump 
}; 

在Boost.MultiIndex的容器,定义为

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; 

现在我有两个数字索引迭代器,一个来自index<by_title>,另一个来自index<by_id>。将这些索引转换为容器的随机访问部分的最简单方法是什么,而不向struct Article添加数据成员?

回答

6

每个索引都支持使用iterator_to按值生成迭代器。如果您已经在一个索引中拥有目标值的迭代器,则可以使用它将其转换为另一个索引中的迭代器。

iterator  iterator_to(const value_type& x); 
const_iterator iterator_to(const value_type& x)const; 

,为了转换为指数则可能可以按照模型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; 
    } 
+0

所以'iterator_to(* it)'应该给我一个随机访问迭代器?我该如何将它转换为数字索引,因为这就是我真正需要的(将索引到矩阵中)? – 2010-11-18 18:06:55

+2

@larsman - 根据random_indexed代码的内部判断,要求是这样的索引上的迭代器是可区分的,即。 'iter - index.begin()'应该工作。请参阅编辑。 – 2010-11-18 18:11:37

6

iterator_to是加速一个相对较新的功能(它的存在,因为1.35)。它使用默认索引时会添加一些语法糖。对于较旧版本的Boost,功能project是唯一的选择。你可以使用project如下:

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. 
+0

是的,这也可以。当我得到新的选票时,我会给你一个+1 :) – 2010-11-18 19:01:49

+0

+1我很好奇@Killill - 在封面下,这个和我的回答似乎都在节点值上使用了'make_iterator'。任何理由选择一个或另一个? – 2010-11-18 19:05:30

+0

可能的原因是,它隐藏了用户的取消引用。我真的不喜欢'<0>'位,尽管... – 2010-11-18 19:19:00