迭代提升 multi_index
Iterating over a boost multi_index
所以。我正在使用 igraph 对象,我想以特定顺序迭代顶点。顺序由名为 "value" 的顶点属性确定,我想按从高到低的顺序进行操作。 igraph 可以按顶点 ID 顺序将所有值作为 igraph_vector_t 提供。如果顶点17的值最大,我想先对它进行操作
在搜索 SO 之后,我开始研究 C++ boost multi_index。这是一个支持结构:
struct indexed_vertex {
igraph_integer_t vid;
igraph_real_t value;
indexed_vertex(igraph_integer_t vid, igraph_real_t value):vid(vid),value(value){}
bool operator<(const indexed_vertex &vertex) const {
return value<vertex.value;
}
};
我创建了以下索引对象:
typedef boost::multi_index::multi_index_container<
indexed_vertex,
boost::multi_index::indexed_by<
boost::multi_index::hashed_unique<
boost::multi_index::member<indexed_vertex, igraph_integer_t, &indexed_vertex::vid>
>,
boost::multi_index::ordered_non_unique<
boost::multi_index::member<indexed_vertex, igraph_real_t, &indexed_vertex::value>
>
>
> indexed_vertex_set;
我的下一个技巧是按降序访问顶点。我尝试过这个(从 docs)但几乎立即失败(嘿!快速失败,对吧?)
indexed_vertex_set ivs;
indexed_vertex_set::nth_index<1>::type::iterator it = ivs.get<1>();
有错误
error: no viable conversion from 'typename nth_index<1>::type' (aka 'boost::multi_index::detail::ordered_index<boost::multi_index::member<indexed_vertex, double, &indexed_vertex::value>, std::__1::less<double>, boost::multi_index::detail::nth_layer<2, indexed_vertex, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::member<indexed_vertex, int, &indexed_vertex::vid>, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::member<indexed_vertex, double, &indexed_vertex::value>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::__1::allocator<indexed_vertex> >, boost::mpl::vector0<mpl_::na>, boost::multi_index::detail::ordered_non_unique_tag, boost::multi_index::detail::null_augment_policy>') to 'indexed_vertex_set::nth_index<1>::type::iterator' (aka 'bidir_node_iterator<node_type>')
indexed_vertex_set::nth_index<1>::type::iterator it = ivs.get<1>();
我尝试了一些其他变体,但总是回到这个错误。我会很感激建议。我以前没有使用过 multi_index,所以我预计我从根本上误解了范围。
奖金问题
既然是假期,我会指出我的下一个任务是做一些类似
的事情
for (vertex in iterator) {
get-vertex-id();
get-vertex-value();
look-up-vertex-and-modify();
}
因此,如果您慷慨解囊,我也非常感谢您的指导。
ivs.get<1>()
给你索引,而不是迭代器。您需要对该索引调用 begin()
、end()
和其他方法来获取迭代器(就像您在容器上所做的那样)。不过你最好使用 typedef
:
indexed_vertex_set ivs;
typedef indexed_vertex_set::nth_index<1>::type sorted_index;
sorted_index &idx = ivs.get<1>();
for( sorted_index::iterator it = idx.begin(); it != idx.end(); ++it ) {
it->vid = 123; // getting access to fields
}
使用 C++11 这可以更简单:
mic_structure mic;
// ...
for (auto & it : mic.get<0>()) {
// do something with iterator
}
所以。我正在使用 igraph 对象,我想以特定顺序迭代顶点。顺序由名为 "value" 的顶点属性确定,我想按从高到低的顺序进行操作。 igraph 可以按顶点 ID 顺序将所有值作为 igraph_vector_t 提供。如果顶点17的值最大,我想先对它进行操作
在搜索 SO 之后,我开始研究 C++ boost multi_index。这是一个支持结构:
struct indexed_vertex {
igraph_integer_t vid;
igraph_real_t value;
indexed_vertex(igraph_integer_t vid, igraph_real_t value):vid(vid),value(value){}
bool operator<(const indexed_vertex &vertex) const {
return value<vertex.value;
}
};
我创建了以下索引对象:
typedef boost::multi_index::multi_index_container<
indexed_vertex,
boost::multi_index::indexed_by<
boost::multi_index::hashed_unique<
boost::multi_index::member<indexed_vertex, igraph_integer_t, &indexed_vertex::vid>
>,
boost::multi_index::ordered_non_unique<
boost::multi_index::member<indexed_vertex, igraph_real_t, &indexed_vertex::value>
>
>
> indexed_vertex_set;
我的下一个技巧是按降序访问顶点。我尝试过这个(从 docs)但几乎立即失败(嘿!快速失败,对吧?)
indexed_vertex_set ivs;
indexed_vertex_set::nth_index<1>::type::iterator it = ivs.get<1>();
有错误
error: no viable conversion from 'typename nth_index<1>::type' (aka 'boost::multi_index::detail::ordered_index<boost::multi_index::member<indexed_vertex, double, &indexed_vertex::value>, std::__1::less<double>, boost::multi_index::detail::nth_layer<2, indexed_vertex, boost::multi_index::indexed_by<boost::multi_index::hashed_unique<boost::multi_index::member<indexed_vertex, int, &indexed_vertex::vid>, mpl_::na, mpl_::na, mpl_::na>, boost::multi_index::ordered_non_unique<boost::multi_index::member<indexed_vertex, double, &indexed_vertex::value>, mpl_::na, mpl_::na>, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, std::__1::allocator<indexed_vertex> >, boost::mpl::vector0<mpl_::na>, boost::multi_index::detail::ordered_non_unique_tag, boost::multi_index::detail::null_augment_policy>') to 'indexed_vertex_set::nth_index<1>::type::iterator' (aka 'bidir_node_iterator<node_type>')
indexed_vertex_set::nth_index<1>::type::iterator it = ivs.get<1>();
我尝试了一些其他变体,但总是回到这个错误。我会很感激建议。我以前没有使用过 multi_index,所以我预计我从根本上误解了范围。
奖金问题
既然是假期,我会指出我的下一个任务是做一些类似
的事情for (vertex in iterator) {
get-vertex-id();
get-vertex-value();
look-up-vertex-and-modify();
}
因此,如果您慷慨解囊,我也非常感谢您的指导。
ivs.get<1>()
给你索引,而不是迭代器。您需要对该索引调用 begin()
、end()
和其他方法来获取迭代器(就像您在容器上所做的那样)。不过你最好使用 typedef
:
indexed_vertex_set ivs;
typedef indexed_vertex_set::nth_index<1>::type sorted_index;
sorted_index &idx = ivs.get<1>();
for( sorted_index::iterator it = idx.begin(); it != idx.end(); ++it ) {
it->vid = 123; // getting access to fields
}
使用 C++11 这可以更简单:
mic_structure mic;
// ...
for (auto & it : mic.get<0>()) {
// do something with iterator
}