Boost.Multi-index은 극도로 복잡한 인터페이스를 제공하는 대신 매우 맞춤화 가능한 인터페이스를 제공하므로 사용자가 고생하는 이유를 쉽게 이해할 수 있습니다.
사용 사례와 일치해야하는 주석이 달린 예제를 제공합니다.
첫째, 우리의 데이터 :
struct X
{
long long l; // assume unique
int i1; // assume unique
int i2; // assume non-unique
// plus any ohter data you have in your class X
};
다음으로, 우리는 우리가 용기를 가지고 할 각 인덱스에 대해 하나 개의 태그를 준비 할 것입니다. 태그 (인덱스 순서에 액세스 할 수 있습니다) 꼭 필요하지 않은, 그러나 각 인덱스의 이름을 제공하는 것이 더 편리 : 이제
struct IndexByL {};
struct IndexByI1 {};
struct IndexByI2 {};
, 우리는 우리가 함께 컨테이너의 종류를 넣어 필요가 :
using Container = boost::multi_index_container<
X*, // the data type stored
boost::multi_index::indexed_by< // list of indexes
boost::multi_index::hashed_unique< //hashed index over 'l'
boost::multi_index::tag<IndexByL>, // give that index a name
boost::multi_index::member<X, long long, &X::l> // what will be the index's key
>,
boost::multi_index::ordered_unique< //ordered index over 'i1'
boost::multi_index::tag<IndexByI1>, // give that index a name
boost::multi_index::member<X, int, &X::i1> // what will be the index's key
>,
boost::multi_index::hashed_non_unique< //hashed non-unique index over 'i2'
boost::multi_index::tag<IndexByI2>, // give that index a name
boost::multi_index::member<X, int, &X::i2> // what will be the index's key
>
>
>;
이제 컨테이너가 생겼습니다. 다음으로, 우리가 그것을 사용하는 방법은 다음과 같습니다
Container c; // empty container
X x1{...}, x2{...}, x3{...}; // some data
// Insert some elements
auto& indexByL = c.get<IndexByL>(); // here's where index tags (=names) come in handy
indexByL.insert(&x1);
indexByL.insert(&x2);
indexByL.insert(&x3);
// Look up by i1
auto& indexByI1 = c.get<IndexByI1>();
auto itFound = indexByI1.find(42);
if (itFound != indexByI1.end())
{
X *x = *itFound;
}
// Look up by i2
auto& indexByI2 = c.get<IndexByI2>();
size_t numberOfHundreds = indexByI2.count(100);
[Live example]
그리고 지금, 짐승은 일반적으로 작동하는 방법에 대한 몇 가지 산문.
다중 인덱스 컨테이너는 저장할 개체 유형 (사용자의 경우)과 저장된 개체에 액세스하는 데 사용할 수있는 하나 이상의 인덱스를 지정하여 정의합니다. 인덱스는 데이터에 액세스하기위한 인터페이스로 생각하십시오.n으로 생각 (핵심하여 동일한 플러스 쉽게 액세스 랭킹을 기준으로
인덱스 (std::set
또는 std::map
생각)
- 인덱스 키에 의해 주문에 따라 :
인덱스는 다른 종류의 수 있습니다 안정된 액세스 순서에 기초하여 키 (std::unordered_set
생각 또는 std::unordered_map
)
- 인덱스에 기초한 해싱 th 요소)
- 인덱스 (01,234,995 생각 안정 위해 랜덤 액세스를 기반으로)
- 인덱스 (
std::vector
생각)
핵심 기반 인덱스도 될 수 있습니다 독특한 (같은 std::map
), 또는 (std::multimap
을 같은) 고유하지 않은.
컨테이너를 정의 할 때 하나의 템플릿 인수로 가져올 각 인덱스를 boost::multi_index::indexed_by
에 전달합니다. 위의 예에서는 3 개의 인덱스를 추가했습니다.
키를 사용하지 않는 인덱스의 경우 (안정적인 순서 & 임의 액세스) 아무 것도 지정하지 않아도됩니다. 당신은 단지 "나는 그런 지수를 원한다"고 말한다.
키 기반 인덱스의 경우 데이터에서 키를 얻는 방법도 지정해야합니다. 그것이 핵심 추출기가 작동하는 곳입니다. (이 예에서 boost::multi_index::member
의 세 가지 용도입니다.) 기본적으로 각 인덱스에 대해 컨테이너에 저장된 데이터에서 키를 추출하기위한 레서피 (또는 알고리즘)를 제공합니다. 현재 키 추출기은 :
- 사용 요소 자체 :
identity
- 사용 요소의 데이터 멤버 :
member
- 사용하여 소자의 (일정한) 멤버 함수 :
[const_]mem_fun
- 사용 전역 함수 : 하나에 여러 개의 키 추출기를 결합
global_fun
- :
composite_key
키 추출기는 포인터를 투명하게 역 참조 할 수 있습니다. 즉, 데이터 요소가 클래스 C
에 대한 포인터 인 경우 클래스 C
이상의 키 추출기를 지정할 수 있으며 참조가 자동으로 수행됩니다. 이 속성은 예제에서도 사용됩니다.
이렇게하면 인덱스가있는 컨테이너가 정의됩니다. 인덱스에 액세스하려면 컨테이너에서 get
멤버 함수 템플릿을 호출합니다. indexed_by
의 템플릿 인수 목록에서 순차 번호를 사용하여 색인을 참조 할 수 있습니다. 보다 읽기 쉬운 조작을 위해 각 색인 (또는 그 중 일부 색인)에 태그를 추가 할 수 있습니다. 태그는 인덱스의 순차 번호 대신 get
에 대한 템플릿 인수로 해당 유형을 사용할 수있는 임의의 유형 (일반적으로 적절한 이름을 가진 빈 구조)입니다. (이 예에서도 사용됩니다).
컨테이너에서 인덱스에 대한 참조를 검색하면 인덱스가 해당하는 데이터 구조 (map, hashset, vector 등)와 마찬가지로 사용할 수 있습니다. 해당 색인을 통해 수행 된 변경 사항은 전체 컨테이너에 영향을 미칩니다.
int 또는 long을 키로 사용 하시겠습니까? 또는 하나의 int와 하나의 long은 동시에? –
당신은 붙어있는 것을 보여줄 필요가 있습니다. 주어진 유일한 답은 많은 유용한 온라인 예제에 링크하는 것입니다. http://stackoverflow.com/help/mcve를 참조하십시오. – sehe
클래스의 X와 (long long), (long), (int), (int) 클래스의 여러 속성이 있습니다. 나는 <(long long), (long), (int), (int)>를 키로 매핑하여 ->로 저장하려고합니다. –
quickdraw