Boost多索引容器代码示例

来源:互联网 发布:台湾战机失联 知乎 编辑:程序博客网 时间:2024/05/16 15:01

问题概述

我们常常需要在代码中维护单个实体类的依据不同键索引的map容器,这通常会在同步上存在麻烦。boost::multi_index_container这个容器就是解决这个问题存在的。

boost::multi_index_container

 STL containers are designed around the concept that each container controls its own collection of elements, giving access to them in a manner specified by the container's type: so, an std::set maintains the elements ordered by a specified sorting criterion, std::list allows for free positioning of elements along a linear sequence, and so on.Sometimes, the necessity arises of having different access interfaces to the same underlying collection: for instance, some data might need to be sorted according to more than one comparison predicate, or a bidirectional list might benefit from a supplemental logarithmic lookup interface. In these situations, programmers typically resort to manual compositions of different containers, a solution that generally involves a fair amount of code devoted to preserve the synchronization of the different parts of the composition. Boost.MultiIndex allows for the specification of multi_index_containers comprised of one or more indices with different interfaces to the same collection of elements. The resulting constructs are conceptually cleaner than manual compositions, and often perform much better. An important design decision has been taken that the indices of a given multi_index_container instantiation be specified at compile time: this gives ample room for static type checking and code optimization.Boost.MultiIndex takes inspiration from basic concepts of indexing arising in the theory of relational databases, though it is not intended to provide a full-fledged relational database framework. multi_index_container integrates seamlessly into the STL container/algorithm design, and features some extra capabilities regarding lookup operations and element updating which are useful extensions even for single-indexed containers.

上边引用boost文档的原文。

示例代码

#include <iostream>#include <boost/multi_index_container.hpp>#include <boost/multi_index/ordered_index.hpp>#include <boost/multi_index/identity.hpp>#include <boost/multi_index/member.hpp>#include <boost/multi_index/mem_fun.hpp>#include <boost/smart_ptr.hpp>#include <boost/lambda/lambda.hpp>#include <boost/lambda/bind.hpp>using namespace std;using namespace ::boost;using namespace ::boost::multi_index;struct employee{    employee(int id,const std::string& ne):id(id)    {        name = boost::make_shared<string>(ne);    }    bool operator<(const employee& e)const{return id<e.id;}    boost::shared_ptr<std::string> getName() const {return name;}public:    int id;public:    /*     因为后期要修改这个值,所以使用public修饰符,但是在mac上运行实例代码的时候发现,声明成private也是可以的,但是放到linux平台使用const函数索引,之后修改其键值又变成不可以,因为返回值是常引用,后来将下边的const_mem_fun替换成member才可以。     */    boost::shared_ptr<std::string> name;};template <class T>struct Compare{    bool operator()(T a, T b)    {        return *a > *b;    }};// define a multiply indexed set with indices by itself, id and nametypedef multi_index_container<boost::shared_ptr<employee>,indexed_by<ordered_unique<identity<employee>>,ordered_unique<member<employee, int, &employee::id>, std::greater<int>>,ordered_non_unique<const_mem_fun<employee, boost::shared_ptr<std::string>, &employee::getName>, Compare<const boost::shared_ptr<std::string>&>//, (*(boost::lambda::_1) > *(boost::lambda::_2)>>> employee_set;/* 上述的多索引容器使用了三种索引策略,第一个是类本身提供的<操作符重载Index0, 第二个使用结构体的成员变量,必须是public修饰符修饰,排序使用降序,不是默认的升序Index1, 第三个使用常成员函数,排序方式使用重载操作符的那一个,对应的有一个mem_fun(非常成员函数),使用lambda不成功 原因不知道 */int main(){    employee_set data;    employee e(9, "qcq");    data.insert(boost::make_shared<employee>(9, "qcq"));    e = employee (8, "rcq");    data.insert(boost::make_shared<employee>(8, "rcq"));    //print_out_by_name(data);    /*     首先使用id索引到要修改的元素迭代器Index0     */    auto item = data.get<1>().find(8);    /*     然后映射到Index1索引的元素迭代器     */    auto item2 = data.project<2>(item);    /*     最后修改item2迭代器指向元素的键值, 使用了lambda,由于指向的是只能指针,因此需要解析地址     */    data.get<2>().modify_key(item2, *(boost::lambda::_1) = "ryz");    for(auto& item : data.get<2>())    {        cout << item->id << "," << *(item->getName()) << endl;    }    return 0;}

代码解释

鄙人是在有这个多索引需求的时候查阅相关文档,但是网络上的很多博客基本上都是直接存储相关的结构体,这段实例代码结合使用了智能指针。思路主要来自boost的官方文档相关章节,并且索引的键值可以是私有,但是可以通过共有的接口访问,这样就不会破坏数据的封装性。
获得一个提示,关于boost的资料还是依据官方的文档为准。

0 0
原创粉丝点击