C++ boost::带比较运算符的多索引容器复合键中的相等\u范围

C++ boost::带比较运算符的多索引容器复合键中的相等\u范围,c++,boost,boost-multi-index,C++,Boost,Boost Multi Index,我试图从多索引容器中查询结果,其中值类型是由三个元素组成的结构。给出了第一个值,但第二个和第三个值必须大于或小于查询参数 在四处搜索后,我发现必须实现自定义密钥提取器,这里的一些链接也提出了相同的建议,但我无法实现它: 有人能帮我把它修好吗 下面是我的结构和多索引实现: #define RANKFILTERVIEW 0 struct TPQ { int UID; int Value; int Rank; TPQ():UID(0),Value(0),Ran

我试图从多索引容器中查询结果,其中值类型是由三个元素组成的结构。给出了第一个值,但第二个和第三个值必须大于或小于查询参数

在四处搜索后,我发现必须实现自定义密钥提取器,这里的一些链接也提出了相同的建议,但我无法实现它:

有人能帮我把它修好吗

下面是我的结构和多索引实现:

#define RANKFILTERVIEW 0

struct TPQ {
    int UID;
    int Value;
    int Rank;
    TPQ():UID(0),Value(0),Rank(0)
    { }
    TPQ(int _T, int _V, int _R):UID(_T),Value(_V),Rank(_R)
    { }
};

typedef bip::allocator<
    TPQ,bip::managed_shared_memory::segment_manager
> shared_struct_allocator;

typedef bmi::multi_index_container<
    TPQ,
    bmi::indexed_by<
        bmi::ordered_unique<bmi::tag<struct Composite>,
            bmi::composite_key<TPQ,
                bmi::member<TPQ, int,&TPQ::UID>,
                bmi::member<TPQ, int,&TPQ::Value>,
                bmi::member<TPQ, int,&TPQ::Rank>
        > >
    >,
    shared_struct_allocator
> Rank_Set;

typedef nth_index<Rank_Set, RANKFILTERVIEW>::type Rank_view;

int main()
{
    bip::managed_shared_memory segment(bip::open_only,"RANKSOTRE");

    int UID =52478;

    std::pair<Rank_Set*, std::size_t> RankOrderRecord=segment.find<Rank_Set>("RANKDATARECORD");

    /// Here I want the result as stated below.
    auto range = RankOrderRecord.first->get<Composite>().equal_range(boost::make_tuple(UID,_2>500,_3>5));

}
#定义RANKFILTERVIEW 0
结构TPQ{
int-UID;
int值;
整数秩;
TPQ():UID(0)、Value(0)、Rank(0)
{ }
TPQ(int_T,int_V,int_R):UID(_T),Value(_V),Rank(_R)
{ }
};
typedef bip::分配器<
TPQ,bip::托管共享内存::段管理器
>共享结构分配器;
typedef bmi::多索引容器<
TPQ,
bmi::按索引索引<
bmi::有序_唯一
>,
共享结构分配器
>秩集;
typedef n_index::type Rank_view;
int main()
{
bip::受管_共享_内存段(bip::仅开放_,“RANKSOTRE”);
int UID=52478;
std::pair RankOrderRecord=segment.find(“RANKDATARECORD”);
///在这里,我想要的结果如下所述。
auto range=RankOrderRecord.first->get().equal_range(boost::make_tuple(UID,_2>500,_3>5));
}

我有一套指示,排序或重新安排将被忽略。

你几乎做到了。实际上,在顺序索引中,您可以通过部分键进行查询。由于场是正则积分类型,因此很容易得出一个好的上下限:

auto range = boost::make_iterator_range(
    view.lower_bound(boost::make_tuple(UID, 501, 6)),
    view.lower_bound(boost::make_tuple(UID+1)));
下面是一个完整的演示:

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/composite_key.hpp>
#include <boost/multi_index/ordered_index.hpp>

#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_mapped_file.hpp> // for Coliru

#include <boost/range/iterator_range.hpp>

#include <iostream>

namespace bmi = boost::multi_index;
namespace bip = boost::interprocess;

struct TPQ {
    int UID   = 0;
    int Value = 0;
    int Rank  = 0;

    TPQ() = default;
    TPQ(int _T, int _V, int _R) : UID(_T), Value(_V), Rank(_R) {}
};

static inline std::ostream& operator<<(std::ostream& os, TPQ const& tpq) {
    return os << "{ UID: " << tpq.UID
              << ", Value: " << tpq.Value
              << ", Rank: " << tpq.Rank << "}";
}

using shared_struct_allocator = bip::allocator<TPQ, bip::managed_mapped_file::segment_manager>;

using Rank_Set = bmi::multi_index_container<
    TPQ,
    bmi::indexed_by<
        bmi::ordered_unique<
            bmi::tag<struct RankFilterView>,
            bmi::composite_key<TPQ,
                bmi::member<TPQ, int, &TPQ::UID>, 
                bmi::member<TPQ, int, &TPQ::Value>,
                bmi::member<TPQ, int, &TPQ::Rank>
            >
        >
    >,
    shared_struct_allocator>;

using Rank_view = bmi::index<Rank_Set, RankFilterView>::type;

int main() {
    bip::managed_mapped_file segment(bip::open_or_create, "RANKSOTRE", 10*1024);
    auto& table = *segment.find_or_construct<Rank_Set>("RANKDATARECORD")(segment.get_segment_manager());

    table.insert({
        {52478, 501, 6}, // Match!
        {52478, 500, 6}, // - Value too small
        {52479, 0,   0}, // - UID too high
        {52478, 502, 6}, // Match!
        {52478, 502, 7}, // Match!
        {52478, 501, 5}, // - Rank too small
        {52477, 502, 7}, // - UID too small
        {52478, 999, 9}, // Match!
    });

    int UID = 52478;
    Rank_view& view = table.get<RankFilterView>(); 

    auto range = boost::make_iterator_range(
        view.lower_bound(boost::make_tuple(UID, 501, 6)),
        view.upper_bound(UID));

    for (TPQ const& tpq : range) {
        std::cout << tpq << "\n";
    }

}

“我有一套指示,排序或重新安排将被忽略。”-你是什么意思?你的意思是,你应该实际使用索引…?而不是
视图。下界(boost::make\u tuple(UID+1))
你可以使用
视图。上界(boost::make\u tuple(UID))
,它不依赖于
UID
的完整性。此外,你可以省去
make\u tuple
而编写
视图。上界(UID)
直接。我很惊讶您不需要定义
RankFilterView
(只声明它)。你有没有解释为什么这样可以?@joaqínMLópezMuñoz mmm。过去我在
上限
方法上出了问题。我不能绝对肯定Boost MultiIndex是否存在这种情况,所以这可能是一种需要一段时间才能“摆脱”的畸形。(测试后更新了答案:)@Caleth-Yup。这只是一份远期申报单。只要没有操作要求类型完整(例如
sizeof(RankFilterView)
),就不需要定义它。这是标记类型的一个非常常见的习惯用法
{ UID: 52478, Value: 501, Rank: 6}
{ UID: 52478, Value: 502, Rank: 6}
{ UID: 52478, Value: 502, Rank: 7}
{ UID: 52478, Value: 999, Rank: 9}