在Boost的multi_index_container中获取不等于x的值

时间:2019-02-27 14:02:44

标签: c++ boost boost-multi-index

我试图对所有不等于boost::multi_index_container中某个值的值进行迭代。

我要访问的索引是一个hashed_non_unique整数。使用我的容器上的equal_range(0)作为映射数据库,我可以访问所有将该特定索引设置为零的容器条目。

我需要的是一个函数,该函数返回索引不为零的所有条目。我在网上搜索了几个小时,只有found个重载函数

std::pair<iterator,iterator> equal_range(
    const CompatibleKey& x,
    const CompatibleHash& hash,const CompatiblePred& eq)const;

但是boost文档只有很少的例子,没有针对这个特定问题的例子。我不知道什么是CompatibleHash或CompatiblePred,但是我尝试过:

    m_mappingDb->get<tags::myIndex>().equal_range(m_mappingDb->begin(), 0, 
        [=](uint32_t lhs, uint32_t rhs) { return lhs != rhs; });

multi_index_container中找到使用lambda作为排序函数的人的例子。

在编译时,我随后在该lambda表达式中收到C2664,表明无法从boost::multi_index::detail::hashed_index_iterator<Node,BucketArray,Category>uint32_t进行转换。因此,我期望我的lambda必须使用迭代器作为参数,但是究竟是哪个呢?什么是Node,BucketArray和Category?

该lambda表达式中还有一个C2064,它声明该函数不是带有1个参数的函数。当然,它需要2。是否必须对此进行比较?

我的替代方法是改用lower_boundupper_bound并将下限设置为1,将上限设置为uint32_t的最大值。但是,我认为这很丑陋。必须有正确的方法来实现不等于函数之类的东西。

1 个答案:

答案 0 :(得分:1)

请注意,equal_range(k)返回一个 range (在此上下文中为一对迭代器),因为它依赖于以下事实:键为k的元素沿着该元素相邻存储。容器顺序:

enter image description here

另一方面,键为 not 等于k的元素不相邻,但属于两个不相交的范围:

enter image description here

因此,equal_range不能扭曲以返回这对范围。如果您绝对需要将两个范围视为一个逻辑范围,则可以求助于Boost.Range's join

template<typename Container,typename Key>
auto not_equal_range(const Container& c,const Key& k)
{
  auto rng=c.equal_range(k);
  return boost::range::join(
    boost::make_iterator_range(c.begin(),rng.first),
    boost::make_iterator_range(rng.second,c.end()));
}

下面是完整的示例。

Live On Coliru

#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/range/iterator_range_core.hpp>
#include <boost/range/join.hpp>

template<typename Container,typename Key>
auto not_equal_range(const Container& c,const Key& k)
{
  auto rng=c.equal_range(k);
  return boost::range::join(
    boost::make_iterator_range(c.begin(),rng.first),
    boost::make_iterator_range(rng.second,c.end()));
}

using namespace boost::multi_index;
using container=multi_index_container<
  int,
  indexed_by<
    hashed_non_unique<identity<int>>
  >
>;

#include <iostream>

int main()
{
  container c={0,0,1,1,2,2,3,4,4,4,5,6,6,6,7};
  for(auto x:not_equal_range(c,4))std::cout<<x<<" ";
}

输出

0 0 1 1 2 2 3 5 6 6 6 7