Boost多指标自定义组合键比较 [英] Boost Multi-Index Custom Composite Key Comparer

查看:225
本文介绍了Boost多指标自定义组合键比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我期待写一个升压 ordered_non_unique 指数与复合键自定义比较。我不完全知道如何做到这一点。升压有一个 composite_key_comparer ,但不会为我工作,因为comparers的关键成员之一,所依赖的previous成员。这是一个简单的例子,但我想索引降序排序上的第三_ 第二_ 是'A'保持0为值第三_ 第一,在所有其他情况下使用std ::少。希望这是有道理的。我想下面的code打印出来:

  3,胡说,A,0
5,胡说,A,11
2,胡说,A,10
4,胡说,A,9
1,胡说,A,8

在code会去代替善有善报HERE ??? 。感谢您的帮助。

 的#include<升压/ multi_index_container.hpp>
#包括LT&;升压/ multi_index / key_extractors.hpp>
#包括LT&;提升/ multi_index / ordered_index.hpp>
#包括LT&;提升/ multi_index / composite_key.hpp>
#包括LT&;&iostream的GT;命名空间BMI =提振:: multi_index;
命名空间BT =提振::元组;结构的Widget
{
  窗口小部件(常量的std ::字符串和ID,常量标准::字符串&放大器; F,char中,无符号整型T)
  :ID_(ID)
  ,first_(F)
  ,second_(S)
  ,third_(T)
  {}  〜小工具(){}  标准::字符串ID_;
  标准::字符串first_;
  焦炭second_;
  无符号整型third_;
};的std :: ostream的&放大器;运营商的LT;< (性病:: ostream的和放大器; OS,const的窗口小部件&安培; W)
{
  OS<< w.id_<< ,&所述;&下; w.first_<< ,&所述;&下; w.second_<< ,&所述;&下; w.third_;
  返回操作系统;
}结构id_index {};
结构other_index {};BMI的typedef :: composite_key<
  窗口小部件*
  BMI ::成员<小部件,标准::字符串,和放大器;的Widget :: first_>中
  BMI ::成员<小部件,焦炭,和放大器;的Widget :: second_>中
  BMI ::成员<小部件,无符号整型,&安培;的Widget :: third_>
> other_key;BMI的typedef multi_index_container中:: LT&;
  窗口小部件*
  BMI ::的indexed_by<
    BMI :: ordered_unique<
      BMI ::标签< id_index>中
      BMI ::成员<小部件,标准::字符串,和放大器;的Widget :: ID_>
    >中
    BMI :: ordered_non_unique<
      BMI ::标签< other_index>中
      other_key,
      ***************善有善报这里?***************
    >
  >
> widget_set;的typedef widget_set ::指数< other_index> ::键入widgets_by_other;
的typedef widgets_by_other:迭代other_index_itr;诠释的main()
{
  widget_set部件;
  widgets_by_other&安培; wbo_index = widgets.get< other_index>();
  窗口小部件*宽;  W =新的小工具(1,嗒嗒,A,8);
  widgets.insert(重量);
  W =新的小工具(2,嗒嗒,A,10);
  widgets.insert(重量);
  W =新的小工具(3,嗒嗒,A,0);
  widgets.insert(重量);
  W =新的小工具(4,嗒嗒,A,9);
  widgets.insert(重量);
  W =新的小工具(5,嗒嗒,A,11);
  widgets.insert(重量);  性病::对< other_index_itr,other_index_itr>范围=
    wbo_index.equal_range(升压:: make_tuple(BLAH,'A'));  而(range.first!= range.second)
  {
    性病::法院LT&;< *(* range.first)LT;<的std :: ENDL;
    ++ range.first;
  }  返回0;
}


解决方案

我想你已经打在了墙上。

您可能想在这里提及:<一href=\"http://www.boost.org/doc/libs/1%5F40%5F0/libs/multi%5Findex/doc/tutorial/basics.html#ord%5Findices\"相对=nofollow>有序索引

由于与STL,你实际上必须自己提供的比较标准,这样的话你必须把它符合您的需要的能力。

在我的链接页面上解释(在'比较predicates部分​​):


  

有序索引说明的最后一部分是关联的比较predicate,必须在低于时尚顺序按键。


因此​​,工作是双重的:


  1. 您需要定义一个合适的比较,predicate,这对你的工作类型

  2. 您需要告诉Boost.MultiIndex的,你想使用这个predicate的钥匙的实际比较

下面是一个例子,我不知道我理解你的要求全面,但这样你可能要检查它确实有点如你所愿。

 结构W​​idgetComparer
{
  布尔运算符()(const的窗口小部件&放大器; LHS,const的窗口小部件&放大器; RHS)常量
  {
    如果(lhs._second =='A'和;&安培; rhs._second =='A')
    {
      返回lhs._third == 0 || rhs._third&LT; lhs._third;
    }
    其他
    {
      返回lhs._third&LT; rhs._third;
    }
  } //运算符()
};

然后,你只需要完成指标。因此取代其它键用的标识&LT;窗口小部件> 的和善有善报HERE用的 WidgetComparer

在这里你去!

重要的一点是,你不应该专注于集装箱的关键的一部分。最关键的是什么本身,它是对(键,比较predicate)来完成实际的排序。重点是关键的文件中,以提高code再利用(特别是,从那些类似的std ::少已经实现比较predicates受益)。

作为替代方案,你可以决定code进行运算符&LT;为你的Widget类或特殊化的std ::少算法。如果您打算使用排序不止一次的这样,你应该preFER此解决方案。但是,如果你的容器将使用它的唯一一个,那么定制predicate更好。

希望这有助于。

I'm looking to write a custom comparer for a boost ordered_non_unique index with a composite key. I'm not exactly sure how to do this. Boost has a composite_key_comparer, but that won't work for me, because one of the comparers for a member of the key depends on a previous member. This is a simplified example, but I want the index to sort descending on third_ when second_ is 'A' keeping 0 values for third_ first and use std::less in all other cases. Hopefully that makes sense. I would like the code below to print out:

3,BLAH,A,0
5,BLAH,A,11
2,BLAH,A,10
4,BLAH,A,9
1,BLAH,A,8

The code would go in place of WHAT GOES HERE???. Thanks for any help.

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

namespace bmi = boost::multi_index;
namespace bt = boost::tuples;

struct Widget
{
  Widget (const std::string& id, const std::string& f, char s, unsigned int t)
  : id_(id)
  , first_(f)
  , second_(s)
  , third_(t)
  { }

  ~Widget () { }

  std::string id_;
  std::string first_;
  char second_;
  unsigned int third_;
};

std::ostream& operator<< (std::ostream& os, const Widget& w)
{
  os << w.id_ << "," << w.first_ << "," << w.second_ << "," << w.third_;
  return os;
}

struct id_index { };
struct other_index { };

typedef bmi::composite_key<
  Widget*,
  bmi::member<Widget, std::string, &Widget::first_>,
  bmi::member<Widget, char, &Widget::second_>,
  bmi::member<Widget, unsigned int, &Widget::third_>
> other_key;

typedef bmi::multi_index_container<
  Widget*,
  bmi::indexed_by<
    bmi::ordered_unique<
      bmi::tag<id_index>,
      bmi::member<Widget, std::string, &Widget::id_>
    >,
    bmi::ordered_non_unique<
      bmi::tag<other_index>,
      other_key,
      ***************WHAT GOES HERE???***************
    >
  >
> widget_set;

typedef widget_set::index<other_index>::type widgets_by_other;
typedef widgets_by_other::iterator other_index_itr;

int main ()
{
  widget_set widgets;
  widgets_by_other& wbo_index = widgets.get<other_index>();
  Widget* w;

  w = new Widget("1", "BLAH", 'A', 8);
  widgets.insert(w);
  w = new Widget("2", "BLAH", 'A', 10);
  widgets.insert(w);
  w = new Widget("3", "BLAH", 'A', 0);
  widgets.insert(w);
  w = new Widget("4", "BLAH", 'A', 9);
  widgets.insert(w);
  w = new Widget("5", "BLAH", 'A', 11);
  widgets.insert(w);

  std::pair<other_index_itr,other_index_itr> range =
    wbo_index.equal_range(boost::make_tuple("BLAH", 'A'));

  while (range.first != range.second)
  {
    std::cout << *(*range.first) << std::endl;
    ++range.first;
  }

  return 0;
}

解决方案

I think you have hit the wall.

You may want to refer here: Ordered Indices

As with the STL, you will actually have to provide the comparison criteria yourself, and thus you will have the ability to tailor it to your needs.

As explained on the page I linked (in 'Comparison Predicates' section):

The last part of the specification of an ordered index is the associated comparison predicate, which must order the keys in a less-than fashion.

Thus, your work is two-fold:

  1. You need to define a suitable comparison predicate, which operates on your types
  2. You need to indicate to Boost.MultiIndex that you wish to use this predicate for the actual comparison of the keys

Here is an example, I am not sure I understood your requirements fully though so you may have to check it indeed sort as you wish.

struct WidgetComparer
{
  bool operator()(const Widget& lhs, const Widget& rhs) const
  {
    if (lhs._second == 'A' && rhs._second == 'A')
    {
      return lhs._third == 0 || rhs._third < lhs._third;
    }
    else
    {
      return lhs._third < rhs._third;
    }
  } // operator()
};

And then, you just have to complete your index. So replace "other key" with identity < Widget > and "WHAT GOES HERE" with WidgetComparer.

And here you goes!

The important point is that you should not focus on the 'key' part of the container. The key is nothing by itself, it is the couple (key,comparison predicate) which does the actual ordering. The focus is on keys in the documentation to enhance code reuse (and in particular, to benefit from the comparison predicates that are already implemented like std::less).

As an alternative, you could have decided to code a "operator<" for your Widget class or to specialize the std::less algorithm. If you intend to use this way of sorting more than once, you should probably prefer this solution. However if your container is the only one which will use it, then a custom predicate is better.

Hope that helped.

这篇关于Boost多指标自定义组合键比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆