关于ZAKER 融媒体解决方案 合作 加入

c- 具有比较运算符的 boost :: multi_index_containe.

CocoaChina 10-13

我正在尝试从多索引容器查询结果 , 其中值类型是三个元素的结构 . 给定第一个值 , 但第二个和第三个必须大于或小于查询参数 .

在四处搜寻之后 , 我发现必须实现自定义的密钥提取器 , 并且此处的某些链接建议相同 , 但是我无法实现它:

> boost::multi_index user-defined key extractor and composite key

> https://www.boost.org/doc/libs/1_62_0/libs/multi_index/test/test_composite_key.cpp

谁能帮我使它正常工作?

下面是我的 struct 和 multiindex 实现:

#define RANKFILTERVIEW 0struct 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 ) ) ;}

我有一组指令 , 要求忽略排序或重新排列 .

最佳答案

差不多了确实 , 您可以通过部分键查询订单索引 . 由于字段是常规整数类型 , 因此很容易得出一个好的上下限:

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

这是完整的演示:

Live On Coliru

#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 << ""; }}

只能按照预期打印:

{ UID: 52478, Value: 501, Rank: 6}{ UID: 52478, Value: 502, Rank: 6}{ UID: 52478, Value: 502, Rank: 7}{ UID: 52478, Value: 999, Rank: 9}

以上内容由"CocoaChina"上传发布 查看原文

觉得文章不错,微信扫描分享好友

扫码分享