入门学习:boost::multi_index多索引容器

    虽然boost::multi_index的声明形式比较特殊,但其确实定义了一个具有多个索引方式的容器!而且,和SQL数据库等类似,它也可以被定义出一个ordered_unique主键,以及多个非unique的其他索引键(ordered_non_unique)。

    多索引容器的unique主键:当新项目被insert时,或者replace时,都要确保新值的主键字段值的唯一性;否则inset() 或 replace() 操作返回失败,新项目也无法插入/更新进去。

    多索引容器的增加、删除、遍历和查找,操作都比较好理解!需要注意的是它的数据项的修改——修改数据之后,必须通过repalce()提交(个人猜测:在replace中实现对修改后的数据更新各个索引)。这也还是说,这个多索引容器和SQL数据库的操作类似!

    至于具体的用法,可以参考下面的代码,自行编译、修改、体验一下!

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <iostream>
#include <iterator>
#include <utility>
//定义学生信息,同理可以使用结构定义
class student {
public:
    int id;
    std::string name;
    int score;
    std::string remark;

    student(int id, std::string name, int score, std::string remark) :id(id), name(std::move(name)), score(score), remark(remark) {
    }

    void print() const {
        std::cout << "[student] id:" << id << ", name:" << name << ", score:" << score << std::endl;
    }

};

// 如果要把student某个属性字段设置为搜索引擎,则需要定义用于排序的空结构体对象
struct _id {};
struct _name{};
struct _score {};

// 定义一个多索引容器——— 它的底层结构是用来存放 结构体的 map 容器 TODO 这个和vector等一样,也是容器!!!
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为唯一索引,类似SQL主键(向本容器中插入新数据时不得冲突)
                boost::multi_index::ordered_non_unique<
                        boost::multi_index::tag<_name>,
                        BOOST_MULTI_INDEX_MEMBER(student, std::string, name) >, // 非唯一索引
                boost::multi_index::ordered_non_unique<
                        boost::multi_index::tag<_score>,
                        BOOST_MULTI_INDEX_MEMBER(student, int, score) >
        >
    >;
// 定义完成!

int boostMultiIndexTest() {
    // initialize data.
    student_table allStu;

    // 插入数据 --- TODO 注意:这个「多索引容器」是一个链式结构(有left/right二叉树式指针)
    allStu.insert(student(3, "xiao", 65, "hello"));
    allStu.insert(student(2, "limi", 90, "hello"));
    allStu.insert(student(1, "lily", 85, "hello"));
    allStu.insert(student(4, "er狗", 80, "hello"));
    allStu.insert(student(5, "Joan", 60, "hello"));

    std::cout << "\n插入时已经默认按照「ordered_unique主键」进行排序了:" << std::endl;
    for (const auto& iter : allStu) {
        iter.print();
    }

    // sort
    std::cout << "\nsort by student id(第一个索引):" << std::endl;
    student_table::index<_id>::type& sort_id = allStu.get<_id>(); ///通过tag<>内的名字,或索引序号,都OK!
    student_table::index<_id>::type::iterator iter_id = sort_id.begin();
    for (; iter_id != sort_id.end(); iter_id++) {
        iter_id->print();
    }

    std::cout << "\nsort by student score(第三个索引):" << std::endl;
    student_table::index<_score>::type& sort_score = allStu.get<2>();
    student_table::index<_score>::type::iterator iter_score = sort_score.begin();
    for (; iter_score != sort_score.end(); iter_score++) {
        iter_score->print();
    }

    std::cout << "\nsort by student name(第二个索引):" << std::endl;
    student_table::index<_name>::type& sort_name = allStu.get<1>();
    student_table::index<_name>::type::iterator iter_name = sort_name.begin();
    for (; iter_name != sort_name.end(); iter_name++) {
        iter_name->print();
    }

    // 查找
    std::cout << "\n通过索引来查找指定项(并可修改条目的数据):" << std::endl;
    student_table::index<_name>::type& find_name = allStu.get<_name>();
    student_table::index<_name>::type::iterator found_item = find_name.find("er狗");
    if (found_item != find_name.end()) { //不是end,就是找到了!
        std::cout << "—— found a student named 「er狗」:" << std::endl;
        found_item->print();

        ///可以在找到之后直接修改 ———— 注意如果是多任务系统,注意要用lock!!!
        student new_ergou = *found_item;
        new_ergou.id = 0;            //TODO 这个id是unique索引Key,可以保持原值,或者其他不能和既有项冲突的值!否则修改不成功!
        new_ergou.name = "二狗";
        new_ergou.score = 91;
        new_ergou.remark = "hello 二狗";
        find_name.replace(found_item, new_ergou); ///实施修改!!!
    }

    std::cout << "\n数据修改之后,再次遍历索引 --sort by student name(第二个索引):" << std::endl;
    //student_table::index<_name>::type& sort_name = allStu.get<1>();
    student_table::index<_name>::type::iterator new_iter_name = sort_name.begin();
    for (; new_iter_name != sort_name.end(); new_iter_name++) {
        new_iter_name->print();
    }
    std::cout << "---------------------------------------------------------\n" << std::endl;

    // 和SQL一样,插入新项时,unique主键不能冲突!!!
    std::cout << "新增一项,项中数据为:" << std::endl;
    std::pair<student_table::iterator, bool> ret = allStu.insert(student(9, "kent", 99, "man"));
    ret.first->print(); //迭代,就是指代一个元素,Java中也是如此!
    std::cout << "新增一项,插入成功否?" << ret.second << std::endl; //bool值
    //遍历核实:
    std::cout << "新增一项,再次遍历如下(核实):" << std::endl;
    student_table::index<_name>::type::iterator new2_iter_name = sort_name.begin();
    for (; new2_iter_name != sort_name.end(); new2_iter_name++) {
        new2_iter_name->print();
    }
    std::cout << "---------------------------------------------------------" << std::endl;

}
  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
boost::asio::high_resolution_timer是一个定时器类,用于在boost::asio中进行高分辨率的定时操作。 boost::asio是一个用于网络和异步编程的C++。它提供了丰富的功能,包括异步IO操作、定时器、socket通信等。其中,boost::asio::high_resolution_timer是其中的一个定时器类,它使用了高分辨率的时钟来进行精确的定时操作。 使用boost::asio::high_resolution_timer,我们可以创建一个定时器对象,并设置定时的时间间隔。可以使用成员函数expires_from_now()指定定时的时间间隔,参数为一个duration类型的对象,表示时间间隔的长度。 例如,以下代码创建了一个定时器对象timer,设置了定时时间间隔为1秒: boost::asio::high_resolution_timer timer(io_context); timer.expires_from_now(boost::posix_time::seconds(1)); 然后,我们可以调用定时器对象的async_wait()函数来启动定时器,并指定一个回调函数,在定时器超时时被调用。回调函数可以是一个lambda函数,也可以是一个函数对象。 例如,以下代码定义了一个lambda函数作为回调函数: timer.async_wait([](const boost::system::error_code& ec) { if (!ec) { // 定时器超时,执行相应操作 } }); 在定时器超时时,回调函数会被触发,并执行相应操作。 总之,boost::asio::high_resolution_timer是一个用于高分辨率定时操作的定时器类,可以帮助我们在异步编程中进行精确的定时操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值