首页 > 解决方案 > 在 boost 的 multi_index_container 中获取不等于 x 的值

问题描述

我正在尝试为所有不等于某个值的值获取迭代器boost::multi_index_container

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

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

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; });

在找到使用 lambda 作为排序函数的示例之后multi_index_container

编译时,我在该 lambda 表达式中收到一个 C2664,无法从boost::multi_index::detail::hashed_index_iterator<Node,BucketArray,Category>to转换。uint32_t所以,我希望我的 lambda 必须使用迭代器作为参数,但究竟是哪个?什么是 Node、BucketArray 和 Category?

该 lambda 表达式中还有另一个 C2064 声明这不是一个接受 1 个参数的函数。当然,它需要2。我必须与之比较吗?

我的替代方法是使用lower_boundandupper_bound并将下限设置为 1,将上限设置为 uint32_t 的最大值。但是,在我看来,这太丑陋了。必须有一种正确的方法来实现类似不等于函数的东西。

标签: c++boostboost-multi-index

解决方案


请注意,它equal_range(k)返回一个范围k(在此上下文中是一对迭代器),因为它依赖于其键存储在容器序列中的元素相邻的事实:

在此处输入图像描述

另一方面,key等于的​​元素k不相邻,而是属于两个不相交的范围:

在此处输入图像描述

所以没有办法equal_range可以扭曲返回这对范围。如果您绝对需要将这两个范围视为一个逻辑范围,您可以求助于Boost.Range 的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

推荐阅读