2010-11-18 3 views
6

Boost 다중 인덱스 반복기에서 숫자 인덱스 가져 오기

로 정의 된 Boost.MultiIndex 컨테이너에 다음

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

을 저장하고 있습니다.

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)는 임의 액세스 반복자를 제공합니까? 그리고 그것을 숫자 인덱스로 변환하려면 어떻게해야합니까? 매트릭스에 인덱스하기 위해 꼭 필요하기 때문입니다. –

+2

@larsman - random_indexed 코드의 내부에서 판단 할 때, 그러한 인덱스에 대한 반복자는 차이가 있습니다. 'iter - index.begin()'이 작동해야합니다. 편집을 참조하십시오. –

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을 줄 것이다 : –

+0

+1 나는 호기심이 많다. @Kyrill -이 기사와 나의 대답은 노드 값에'make_iterator '를 사용하는 것 같다. 하나 또는 다른 것을 선호하는 이유는 무엇입니까? –

+0

이 방법을 선호하는 이유는 사용자가 역 참조를 숨길 수 있기 때문입니다. 그래도'<0>'비트가 아니라 ... –