Итерация над повышением multi_index

ТАК. Я работаю с объектом igraph и хочу перебирать вершины в определенном порядке. Порядок определяется атрибутом вершины под названием «значение», и я хотел бы работать с наивысшего к наименьшему. igraph может предоставить все значения в виде igraph_vector_t в порядке идентификатора вершины. Если вершина 17 имеет наибольшее значение, я хочу сначала оперировать ею.

После поиска SO, я начал изучать C ++ повысить мульти_индекс. Вот вспомогательная структура:

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;

Мой следующий трюк — посещение вершин в порядке убывания. Я пытался это (из документы) но терпят неудачу почти мгновенно (эй! быстро проваливаются, верно?)

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

Так что, если вы чувствуете себя щедрым, я также буду признателен за руководство.

1

Решение

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
}
3

Другие решения

С C ++ 11 это может быть проще:

mic_structure mic;

// ...

for (auto & it : mic.get<0>()) {
// do something with iterator
}
2

По вопросам рекламы [email protected]