每一部分都单独注释的,运行时取消注释,将其他部分注释起来就可以。
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <iostream>
#include <string>
/*
Boost.MultiIndex 让我们可以自定义新的容器。
Boost.MultiIndex 并没有提供任何特定的容器而是一些类来方便我们定义新的容器。
典型的做法是: 你需要用到 typedef 来为你的新容器提供对 Boost.MultiIndex 中类的方便的访问。
Boost.MultiIndex 的容器最大的优势在于: 他对一组同样的数据提供了多组访问接口。
*/
struct person
{
std::string name;
int age;
person(const std::string &n, int a)
: name(n), age(a)
{
}
};
/*
每个容器定义都需要的类 boost::multi_index::multi_index_container
第一个参数是容器中储存的元素类型, 在例子中是 person;
第二个参数指明了容器所提供的所有索引类型。
************************分割
访问接口的具体细节都可以在定义容器时被指定。
接口的定义必须借由模板类 boost::multi_index::indexed_by 来实现。
每一个接口都作为参数传递给它。
*/
/*
例子中定义了两个 boost::multi_index::hashed_non_unique 类型的接口,
boost::multi_index::hashed_non_unique 是一个模板类, 他需要一个可计算 Hash 值的类型作为它的参数。
因为接口需要访问 person 中的 name 和 age, 所以 name 和 age 都要是可计算 Hash 值的。
辅助模板类 boost::multi_index::member 来访问类中的属性。
指定了好几个参数来让 boost::multi_index::member 明白可以访问 person 中的哪些属性以及这些属性的类型。
person_multi可以分别通过其中的两个属性 name 和 age 来查询容器。
*/
typedef boost::multi_index::multi_index_container<
person,
boost::multi_index::indexed_by<
boost::multi_index::hashed_non_unique<
boost::multi_index::member<
person, std::string, &person::name
>
>,
boost::multi_index::hashed_non_unique<
boost::multi_index::member<
person, int, &person::age
>
>
>
> person_multi;
void set_age(person &p)
{
p.age = 32;
}
/*
为了确保容器中存储的值是唯一的, 你可以使用 boost::multi_index::hashed_unique 接口。
所有要被存入容器中的值都必须满足它的接口的限定。 只要一个接口限定了容器中的值必须是唯一的,
那其他接口都不会对该限定造成影响。
下面的第一个接口不唯一,第二个接口唯一
*/
typedef boost::multi_index::multi_index_container<
person,
boost::multi_index::indexed_by<
boost::multi_index::hashed_non_unique<
boost::multi_index::member<
person, std::string, &person::name
>
>,
boost::multi_index::hashed_unique<
boost::multi_index::member<
person, int, &person::age
>
>
>
> person_multi1;
int test02()
{
//person_multi persons;
/*
如果用 insert() 或者 count() 来直接访问 persons 对象, 第一个接口会被隐式的调用
*/
/*persons.insert(person("Boris", 31));
persons.insert(person("Anton", 35));
persons.insert(person("Caesar", 25));
*/
//std::cout << persons.count("Boris") << std::endl;
///*
//想要访问第二个接口, 你需要调用 get() 函数并且传入想要访问的接口的索引值。
//函数 get() 的返回值是一个用来访问 MultiIndex 容器的类 nth_index ,也需要指定需要访问的接口的索引值 这个值肯定跟 get() 函数指定的模板参数是一样的。
//最后一步: 用 :: 来得到 nth_index 的 type
//*/
//const person_multi::nth_index<1>::type &age_index = persons.get<1>();
///*
// age_index 就是一个通过 age 来访问的 Hash 容器。
//*/
//std::cout << age_index.count(25) << std::endl;
/*
MultiIndex 容器中的值也不允许被修改。 严格的说, 所有存储在 MultiIndex 中的元素都该是常量。
为了避免删除或修改其中元素真正的值, Boost.MultiIndex 提供了一些常用函数来操作其中的元素。
使用这些函数来操作 MultiIndex 容器中的值并不会引起那些元素所指向的真正的对象改变, 所以更新动作是安全的。
而且所有接口都会被通知这种改变, 然后去重新计算新的 Hash 值等。
*/
/*
//通过迭代器访问元素
每个 Boost.MultiIndex 中的接口都支持 modify() 函数来提供直接对容器本身的操作。
它的第一个参数是一个需要更改对象的迭代器;
第二参数则是一个对该对象进行操作的函数。
*/
/*person_multi::iterator it = persons.find("Boris");
persons.modify(it, set_age);
const person_multi::nth_index<1>::type &age_index = persons.get<1>();
std::cout << age_index.count(32) << std::endl;*/
person_multi1 persons;
persons.insert(person("Boris", 31));
persons.insert(person("Anton", 31));
persons.insert(person("Caesar", 25));
/*
通过接口1 age来访问元素,由于接口1 是唯一的,只有一个,不允许相同age的person传入。
*/
const person_multi1::nth_index<1>::type &age_index = persons.get<1>();
std::cout << age_index.count(31) << std::endl;
system("pause");
return 0;
}