在 boost 中获取的值不等于 x multi_index_container
Getting values not equals x in boost's multi_index_container
我正在尝试为所有不等于 boost::multi_index_container
中特定值的值获取迭代器。
我要访问的索引是一个 hashed_non_unique
整数。在用作映射数据库的容器上使用 equal_range(0)
,我能够访问将此特定索引设置为零的所有容器条目。
我需要的是 returns 索引不为零的所有条目的函数。我在网上搜索了几个小时,只有 found 重载函数
std::pair<iterator,iterator> equal_range(
const CompatibleKey& x,
const CompatibleHash& hash,const CompatiblePred& eq)const;
但是 boost 文档只有很少的示例,并且 none 针对这个特定问题。我不知道 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 必须使用迭代器作为参数,但究竟是哪个呢?什么是节点、BucketArray 和类别?
该 lambda 表达式中还有另一个 C2064,指出这不是一个接受 1 个参数的函数。当然,需要2。我是否必须与此进行比较?
我的替代方案是使用 lower_bound
和 upper_bound
并将下限设置为 1,将上限设置为 uint32_t 的最大值。但是,在我看来,这太丑陋了。必须有一个正确的方法来实现类似不等于函数的东西。
请注意,equal_range(k)
return 是一个 range(在此上下文中的一对迭代器),因为它依赖于键为 k
沿着容器序列相邻存储:
另一方面,键不等于k
的元素不相邻,但属于两个不相交的范围:
所以equal_range
不可能扭曲成return这对范围。如果您绝对需要将这两个范围视为一个逻辑范围,您可以求助于 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()));
}
完整示例如下。
#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
我正在尝试为所有不等于 boost::multi_index_container
中特定值的值获取迭代器。
我要访问的索引是一个 hashed_non_unique
整数。在用作映射数据库的容器上使用 equal_range(0)
,我能够访问将此特定索引设置为零的所有容器条目。
我需要的是 returns 索引不为零的所有条目的函数。我在网上搜索了几个小时,只有 found 重载函数
std::pair<iterator,iterator> equal_range(
const CompatibleKey& x,
const CompatibleHash& hash,const CompatiblePred& eq)const;
但是 boost 文档只有很少的示例,并且 none 针对这个特定问题。我不知道 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 必须使用迭代器作为参数,但究竟是哪个呢?什么是节点、BucketArray 和类别?
该 lambda 表达式中还有另一个 C2064,指出这不是一个接受 1 个参数的函数。当然,需要2。我是否必须与此进行比较?
我的替代方案是使用 lower_bound
和 upper_bound
并将下限设置为 1,将上限设置为 uint32_t 的最大值。但是,在我看来,这太丑陋了。必须有一个正确的方法来实现类似不等于函数的东西。
请注意,equal_range(k)
return 是一个 range(在此上下文中的一对迭代器),因为它依赖于键为 k
沿着容器序列相邻存储:
另一方面,键不等于k
的元素不相邻,但属于两个不相交的范围:
所以equal_range
不可能扭曲成return这对范围。如果您绝对需要将这两个范围视为一个逻辑范围,您可以求助于 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()));
}
完整示例如下。
#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