我正在寻找使用复合键为boost ordered_non_unique
索引编写自定义比较器。我不确定如何做到这一点。 Boost有composite_key_comparer
,但这对我不起作用,因为密钥成员的一个比较器依赖于前一个成员。这是一个简化的示例,但我希望当third_
为'A'时,索引在second_
上降序排序,首先保留third_
的0值,并在所有其他情况下使用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;
}
答案 0 :(得分:4)
我认为你已经碰壁了。
您可以在此处参考:Ordered Indices
与STL一样,您实际上必须自己提供比较标准,因此您可以根据自己的需要进行定制。
正如我链接的页面(在'比较谓词'部分中)所解释的那样:
有序索引规范的最后一部分是关联的比较谓词,它必须以不太方式对键进行排序。
因此,你的工作是双重的:
这是一个例子,我不确定我完全理解你的要求,所以你可能必须按照你的意愿检查它。
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()
};
然后,您只需要完成索引。因此,将“其他密钥”替换为 identity&lt;使用 WidgetComparer 的小部件&gt; 和“WHAT GOES HERE”。
你来了!
重要的是,您不应该专注于容器的“关键”部分。关键是什么都不是,它是实际排序的夫妻(关键,比较谓词)。重点是文档中的键,以增强代码重用(特别是,从已经实现的比较谓词中受益,如std :: less)。
作为替代方案,您可以决定编写“运算符&lt;”您的Widget类或专门用于std :: less算法。如果您打算多次使用这种排序方式,您应该更喜欢这种解决方案。但是,如果您的容器是唯一将使用它的容器,那么自定义谓词就更好了。
希望有所帮助。