2010-11-18 53 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