【问题标题】:How to extract a conditional range from ordered composite boost::multi_index如何从有序复合 boost::multi_index 中提取条件范围
【发布时间】:2021-03-03 13:59:25
【问题描述】:

在以下简化示例中:

struct SalesRecord
{
    time_t date;
    std::string department;
    int sales_person_id;

    int num_sales;
    int total_num_sales;
};

typedef multi_index_container
    <
        SalesRecPtr,
        indexed_by
        <
            ordered_unique // 0
            <
                composite_key
                <
                    SalesRecPtr,
                    member <SalesRecord, time_t,      &SalesRecord::date>,
                    member <SalesRecord, std::string, &SalesRecord::department>,
                    member <SalesRecord, int,         &SalesRecord::sales_person_id>
                >,
                composite_key_compare
                <
                    std::greater<time_t>,
                    std::less<std::string>,
                    std::less<int>
                >
            >,
            ordered_unique // 1
            <
                composite_key
                <
                    SalesRecPtr,
                    member <SalesRecord, std::string, &SalesRecord::department>,
                    member <SalesRecord, int,         &SalesRecord::sales_person_id>,
                    member <SalesRecord, time_t,      &SalesRecord::date>
                >,
                composite_key_compare
                <
                    std::less<std::string>,
                    std::less<int>,
                    std::greater<time_t> // could also be std::less  here
                >
            >
        >
    > SALES_RECORDS;

此 SALES_RECORDS 集合可能包含按每天进行至少一次销售的个人和部门的销售记录。部门“Dep1”的人“A”可能在日期 1、3、4、5、20 有销售;

问。如何从这个集合中获取一个范围,在第 4 天之后找到这个人(“A”)、部门(“Dep1”)的所有记录? 这可用于在更正特定日期的销售数量后更新销售总数。 目前,我正在检索一个人的 equal_range 并迭代到所需的日期,这给我的搜索增加了不希望的线性复杂性。

【问题讨论】:

    标签: boost-multi-index


    【解决方案1】:
    tm     t{0,0,0,4,2,121,4}; // Mar 4, 2021
    time_t tt=mktime(&t);
    int    person_id=5;
    
    auto first=sales_records.get<1>().lower_bound(std::make_tuple("Dep1",person_id)),
         last =sales_records.get<1>().lower_bound(std::make_tuple("Dep1",person_id,tt));
    

    更新:同样的事情可以用range(示例中使用C++14)来完成:

    auto p=sales_records.get<1>().range(
        [cmp=sales_records.get<1>().key_comp(),from=std::make_tuple("Dep1",person_id)   ]
        (const auto& x){return !cmp(x,from);},
        [cmp=sales_records.get<1>().key_comp(),to  =std::make_tuple("Dep1",person_id,tt)]
        (const auto& x){return cmp(x,to);});
    

    但生成的代码确实比range-less 替代方案要麻烦得多。

    【讨论】:

    • 谢谢!最初我认为有一种方法可以使用“sales_records.get().range()”。
    • range也可以用,更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多