C++ Boost多索引自定义复合密钥比较器

C++ Boost多索引自定义复合密钥比较器,c++,boost,indexing,C++,Boost,Indexing,我想为带有复合键的boostordered\u non\u unique索引编写一个自定义比较器。我不知道该怎么做。Boost有一个复合密钥\u比较器,但这对我来说不起作用,因为密钥成员的一个比较器依赖于前一个成员。这是一个简化的示例,但我希望索引在second为“a”时按third降序排序,并在所有其他情况下使用std::less。希望这是有道理的。我希望打印出以下代码: 3,BLAH,A,0 5,BLAH,A,11 2,BLAH,A,10 4,BLAH,A,9 1,BLAH,A,8 代码将

我想为带有复合键的boost
ordered\u non\u unique
索引编写一个自定义比较器。我不知道该怎么做。Boost有一个
复合密钥\u比较器
,但这对我来说不起作用,因为密钥成员的一个比较器依赖于前一个成员。这是一个简化的示例,但我希望索引在
second
为“a”时按
third
降序排序,并在所有其他情况下使用std::less。希望这是有道理的。我希望打印出以下代码:

3,BLAH,A,0
5,BLAH,A,11
2,BLAH,A,10
4,BLAH,A,9
1,BLAH,A,8
代码将取代这里的内容。谢谢你的帮助

#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;
}
#包括
#包括
#包括
#包括
#包括
命名空间bmi=boost::multi_索引;
名称空间bt=boost::tuples;
结构小部件
{
小部件(const std::string&id、const std::string&f、char s、unsigned int t)
:id(id)
,第一(f)
,二(s)
,第三组(t)
{ }
~Widget(){}
std::字符串id;
std::字符串优先;
第二字符;
无符号整数;
};

std::ostream&operator我想你撞到墙了

您可能希望在此处参考:

与STL一样,您实际上必须自己提供比较标准,因此您将能够根据自己的需要对其进行调整

如我链接的页面(在“比较谓词”部分)所述:

有序索引规范的最后一部分是关联的比较谓词,它必须以小于的方式对键进行排序

因此,您的工作有两个方面:

  • 您需要定义一个合适的比较谓词,它对您的类型进行操作
  • 您需要向Boost.MultiIndex指示您希望使用此谓词进行键的实际比较
  • 这里是一个例子,我不确定我是否完全理解您的要求,尽管如此,您可能需要检查它是否确实符合您的要求

    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()
    };
    
    结构WidgetComparer { 布尔运算符()(常量小部件和lhs、常量小部件和rhs)常量 { 如果(左秒='A'和右秒='A') { 返回左侧。|第三个==0 | |右侧。|第三个<左侧。|第三个; } 其他的 { 返回左三<右三; } }//运算符() };
    然后,你只需要完成你的索引。因此,用identity替换“other key”,用WidgetComparer替换“WHAT go HERE”

    给你

    重要的一点是,您不应该关注容器的“关键”部分。键本身什么都不是,它是执行实际排序的耦合(键,比较谓词)。重点放在文档中的键上,以增强代码重用(特别是从已经实现的比较谓词(如std::less)中获益)

    作为替代方案,您可以决定编写一个“运算符”