Boost多索引容器库(Multi-index)提供了一个名为multi_index_container的类模板,它支持构建容器来维护一个或多个具有不同排序和访问语义的索引。其提供了类似于STL容器的接口,使其使用变得容易。在相同的元素集合上进行多索引的概念是从关系数据库术语中借用的,它允许以多索引关系表的形式指定复杂的数据结构,在这种情况下,简单的集合和映射是不够的。Multi-index提供了广泛的索引选择,模拟了类似的STL容器,如std::set、std::list和std::unordered_set。
Boost.Multi-index提供了额外的功能,比如子对象搜索、范围查询、元素的就地更新和秩的计算,这使得它可以方便地替代std::set和set::multiset,即使不需要多索引功能。
以下通过一个实例说明Boost.Multi-index的使用:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/shared_ptr.hpp>
using namespace std;
//定义学生信息,同理可以使用结构定义
class student {
public:
student(int id, string name, int score, string remark) :id(id), name(name), score(score), remark(remark) {
}
void print() const {
cout << "id:" << id << " name:" << name << " score:" << score << endl;
}
int id;
string name;
int score;
string remark;
};
// 如果要把student某个属性字段设置为搜索引擎,则需要定义用于排序的空结构体对象
struct _id {};
struct _name{};
struct _score {};
// 定义一个multi_index_container(多索引容器)
using student_table =
boost::multi_index::multi_index_container<
student,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<boost::multi_index::tag<_id>, BOOST_MULTI_INDEX_MEMBER(student, int, id)>, // ID为唯一索引,类似主键
boost::multi_index::ordered_non_unique<boost::multi_index::tag<_name>, BOOST_MULTI_INDEX_MEMBER(student, string, name)>, // 非唯一索引
boost::multi_index::ordered_non_unique<boost::multi_index::tag<_score>, BOOST_MULTI_INDEX_MEMBER(student, int, score)>
>
>;
int main() {
// initialize data.
student_table allStu;
allStu.insert(student(1, "lili", 85, "hello"));
allStu.insert(student(2, "liming", 90, "hello"));
allStu.insert(student(3, "xiaoming", 65, "hello"));
allStu.insert(student(4, "ergou", 80, "hello"));
allStu.insert(student(5, "dagou", 60, "hello"));
// sort
student_table::index<_id>::type& sort_id = allStu.get<0>();
cout << "sort by student id:" << endl;
student_table::index<_id>::type::iterator iter_id = sort_id.begin();
for (; iter_id != sort_id.end(); iter_id++) {
iter_id->print();
}
cout << "\n" << endl;
student_table::index<_name>::type& sort_name = allStu.get<1>();
cout << "sort by student name:" << endl;
student_table::index<_name>::type::iterator iter_name = sort_name.begin();
for (; iter_name != sort_name.end(); iter_name++) {
iter_name->print();
}
cout << "\n" << endl;
student_table::index<_score>::type& sort_score = allStu.get<2>();
cout << "sort by student score:" << endl;
student_table::index<_score>::type::iterator iter_score = sort_score.begin();
for (; iter_score != sort_score.end(); iter_score++) {
iter_score->print();
}
cout << "\n" << endl;
// find
student_table::index<_name>::type& find_name = allStu.get<_name>();
student_table::index<_name>::type::iterator iter_ergou = find_name.find("ergou");
if (iter_ergou != find_name.end()) {
cout << "find a student named ergou:" << endl;
iter_ergou->print();
// modify ergou
student ergou = *iter_ergou;
ergou.id = 6; // will be success. becasuse id 6 not in the table. otherwise failure
ergou.name = "ergou_v2";
ergou.score = 91;
ergou.remark = "hello ergou";
bool isSuc = find_name.replace(iter_ergou, ergou);
}
//
cout << "sort by student id after replace ergou:" << endl;
student_table::index<_id>::type::iterator iter_id_v2 = sort_id.begin();
for (; iter_id_v2 != sort_id.end(); iter_id_v2++) {
iter_id_v2->print();
}
cout << "\n" << endl;
system("pause");
}
执行结果: