【问题标题】:Iterating over a boost multi_index迭代 boost multi_index
【发布时间】:2016-03-23 05:12:03
【问题描述】:

所以。我正在使用 igraph 对象,我想以特定顺序迭代顶点。顺序由称为“值”的顶点属性确定,我想从最高到最低进行操作。 igraph 可以按顶点 id 顺序将所有值作为 igraph_vector_t 提供。如果顶点 17 的值最高,我想先对其进行操作。

搜索完之后,我开始研究 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();
}

因此,如果您觉得大方,我也很感激那里的指导。

【问题讨论】:

    标签: c++ boost igraph boost-multi-index


    【解决方案1】:

    ivs.get&lt;1&gt;() 给你索引,而不是迭代器。您需要在该索引上调用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 很陌生。我应该将 typedef 放在我的头文件中吗?
    • 是的,你绝对可以像你 typedef boost::multi_index::multi_index_container 本身一样。您可能希望本地化该名称以避免冲突,但该单独的主题。
    • 并扭转它,我应该这样做it=idx.end()-1; it!=idx.begin() 吗?
    • 不,最好使用rbegin() rend() - 因为它!=idx.begin() 将丢失一个元素,而idx.end()-1 将仅适用于某些索引(提供随机访问)
    • 很棒的提示,最后是for (ivs_sorted::reverse_iterator it = idx.rbegin(); it!=idx.rend() &amp;&amp; i&lt;k; ++it) { std::cout &lt;&lt; "vid/value: " &lt;&lt; it-&gt;vid &lt;&lt; " / " &lt;&lt; it-&gt;value &lt;&lt; "!" &lt;&lt; std::endl; }
    【解决方案2】:

    使用 C++11 可以更简单:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-29
      • 2017-01-27
      • 1970-01-01
      相关资源
      最近更新 更多