一个多索引,其中一个索引是整个集合的子集
A multi-index where one index is a subset of the whole collection
我想构建一个具有两个sequenced
视图的多索引,其中我只能从一个视图中删除值。
在代码中:
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <algorithm>
#include <iterator>
#include <vector>
using namespace boost::multi_index;
typedef multi_index_container<
int,
indexed_by<
sequenced<>,
sequenced<>
>
> container;
int main()
{
container c;
std::vector<int>
// complete
data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
// only uneven
uneven_data;
std::copy_if(begin(data), end(data),
std::back_inserter(uneven_data),
[](int i) { return i % 2 != 0; });
container cont;
std::copy(begin(data), end(data), std::back_inserter(cont));
auto& idx0 = cont.get<0>();
auto& idx1 = cont.get<1>();
// remove all uneven from idx1
idx1.remove_if([](int i) { return i % 2 == 0; });
// behavior I would like to be true, but now both idx0 and idx1 are
// equal to uneven_data
assert(std::equal(begin(data), end(data), begin(idx0)));
assert(std::equal(begin(uneven_data), end(uneven_data), begin(idx1)));
return 0;
}
boost::multi_index
这样的事情可能吗?
No.在升压multi_index_container中,指数作为相同值的单独视图耦合在一起。 这是提升multi_index_containers的重要保证。
"Boost.MultiIndex允许规范 multi_index_containers由一个或多个具有不同 与同一元素集合的接口"(提升multi_index教程)。
使用两个不同的排序<>索引,您可以通过两种不同的方式重新排列顺序,但它们都必须包含所有值。
如果您希望根据布尔谓词查看元素子集(例如:值为奇数),请考虑使用 boost::filter_iterator。 这不会尝试擦除容器中的值,而是在迭代期间跳过它们。
或者,可以通过排序来获得选择/过滤,使用带有适当键提取器的multi_index ordered_non_unique索引。
例如,基于键提取器[](int i) { return i % 2; }
的ordered_non_unique索引会将奇数值和偶数值放在不同的组中,因此可以使用 equal_range 获得所有奇数值的迭代器范围。
正如我上面提到的,一种使用提升侵入的更灵活(非基于谓词)的方法。 使用两个或多个列表钩子,可以使一个对象同时参与两个或多个序列。
#include <boost/intrusive/list.hpp>
#include <boost/foreach.hpp>
#include <algorithm>
#include <memory>
#include <iostream>
namespace intr = boost::intrusive;
template<class Value>
struct Sequence2
{
typedef intr::link_mode< intr::auto_unlink > AutoUnlinkMode;
typedef intr::list_member_hook< AutoUnlinkMode > SeqHook;
struct Node
{
Node( const Value& i ) : value(i) {}
operator Value&()
{
return value;
}
Value value;
SeqHook mainHook;
SeqHook hook0;
SeqHook hook1;
};
typedef intr::member_hook< Node, SeqHook,&Node::mainHook > UsingMainHook;
typedef intr::member_hook< Node, SeqHook,&Node::hook0 > UsingSeqHook0;
typedef intr::member_hook< Node, SeqHook,&Node::hook1 > UsingSeqHook1;
typedef intr::constant_time_size<false> NonConstantTimeSized;
typedef intr::list< Node, UsingMainHook, NonConstantTimeSized > NodesList;
typedef intr::list< Node, UsingSeqHook0, NonConstantTimeSized > Sequence0;
typedef intr::list< Node, UsingSeqHook1, NonConstantTimeSized > Sequence1;
NodesList nodes;
Sequence0 seq0;
Sequence1 seq1;
typename NodesList::iterator insert( const Value& item )
{
Node* node = new Node(item);
nodes.push_back( *node );
typename NodesList::iterator iter = nodes.end(); iter--;
seq0.push_back( *node );
seq1.push_back( *node );
return iter;
}
typename Sequence0::iterator iterator0( typename NodesList::iterator iter )
{
return seq0.iterator_to( *iter );
}
typename Sequence1::iterator iterator1( typename NodesList::iterator iter )
{
return seq1.iterator_to( *iter );
}
//! Erase from both sequences
void erase( typename NodesList::iterator at )
{
nodes.erase_and_dispose( at, std::default_delete<Node>() );
}
//! Erase from sequence 0
void erase( typename Sequence0::iterator at )
{
Node& n = *at;
assert( n.hook0.is_linked() );
if( ! n.hook1.is_linked() )
{
seq0.erase_and_dispose( at, std::default_delete<Node>() );
}
else
{
seq0.erase(at);
}
}
//! Erase from sequence 1
void erase( typename Sequence1::iterator at )
{
Node& n = *at;
assert( n.hook1.is_linked() );
if( ! n.hook0.is_linked() )
{
seq1.erase_and_dispose( at, std::default_delete<Node>() );
}
else
{
seq1.erase(at);
}
}
~Sequence2()
{
nodes.clear_and_dispose( std::default_delete<Node>() );
}
};
template< class T >
void show( Sequence2<T>& mseq, const std::string& comment )
{
std::cout << comment << "nseq 0:t";
BOOST_FOREACH( T& i, mseq.seq0 )
{
std::cout << i << " ";
}
std::cout << "nseq 1:t";
BOOST_FOREACH( T& i, mseq.seq1 )
{
std::cout << i << " ";
}
std::cout << "nn";
}
int main(void)
{
Sequence2< std::string > mseq;
mseq.insert( "." );
auto iterX = mseq.insert("X");
auto iterY = mseq.insert("Y");
auto iterZ = mseq.insert("Z");
mseq.insert(".");
mseq.insert(".");
show(mseq, "start" );
mseq.seq0.reverse();
show(mseq, "after reverse seq0");
mseq.erase( mseq.iterator0(iterY) );
show(mseq, "after erase Y in seq0");
// Update a value in both sequences
std::string& v = *iterZ;
v = "z";
show(mseq, "after modify Z in both");
mseq.erase( iterX );
show(mseq, "after erase X in both");
mseq.erase( iterY );
show(mseq, "after erase Y in both");
return 0;
}
它产生:
start
seq 0: . X Y Z . .
seq 1: . X Y Z . .
after reverse seq0
seq 0: . . Z Y X .
seq 1: . X Y Z . .
after erase Y in seq0
seq 0: . . Z X .
seq 1: . X Y Z . .
after modify Z in both
seq 0: . . z X .
seq 1: . X Y z . .
after erase X in both
seq 0: . . z .
seq 1: . Y z . .
after erase Y in both
seq 0: . . z .
seq 1: . z . .
相关文章:
- 给定一个向量,如何找到该向量的所有子集和的原始索引
- 在矢量中使用擦除时双重释放或损坏(快速顶部).如何擦除一个矢量的几个项目知道它们的索引?
- 一个 2D 数组,并按行存储值.第一个循环用于行索引,第二个循环用于列索引
- 如何访问委托的paint()函数中的另一个索引?
- 查找下一个具有真值C++的数组索引
- CPP:如何获取字符的最后一个索引
- 是否有一个类似STL的函数来用索引的某个函数填充数组
- 我正在尝试将我的 c++ 数组从第二个索引切到最后一个索引
- 如何根据另一个向量中给出的索引拆分向量?
- 如何用索引命名一个变量来存储输入 mxArray?
- "如何使用C++将字符串的第一个和最后一个索引返回到向量中?
- 查找数组的第一个和最后一个索引,其中 from 和 to 元素的顺序总和最大
- 数组:如何在指定索引之前显示数组的第一个和最后一个元素以及数组元素的差异?
- 数组 - 最后一个索引
- C++:检查向量中的元素是否大于另一个具有相同索引的元素的有效方法?
- 创建一个没有指针但有索引的链表
- 在向量C++中查找特定的第一个和最后一个索引<float>
- 编写一个递归功能,该功能采用数组并以相反顺序显示元素,而无需在末尾启动数组的索引
- 在C 字符串中,为什么在最后一个字符之后,通过索引和()访问索引时行为是不同的
- 如何给枚举值的索引一个得到它?