【问题标题】:Get numeric index from Boost multi-index iterator从 Boost 多索引迭代器获取数字索引
【发布时间】:2011-05-12 04:47:01
【问题描述】:

我正在存储一堆以下内容

struct Article {
    std::string title;
    unsigned db_id;     // id field in MediaWiki database dump
};

在 Boost.MultiIndex 容器中,定义为

typedef boost::multi_index_container<
    Article,
    indexed_by<
        random_access<>,
        hashed_unique<tag<by_db_id>,
                      member<Article, unsigned, &Article::db_id> >,
        hashed_unique<tag<by_title>,
                      member<Article, std::string, &Article::title> >
    >
> ArticleSet;

现在我有两个迭代器,一个来自index&lt;by_title&gt;,一个来自index&lt;by_id&gt;。在不向struct Article 添加数据成员的情况下,将这些索引转换为容器的随机访问部分的最简单方法是什么?

【问题讨论】:

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


    【解决方案1】:

    iterator_to 是 Boost 中一个相对较新的功能(从 1.35 开始就有)。与默认索引一起使用时,它会添加一些语法糖。对于旧版本的 Boost,函数 project 是唯一的选择。您可以使用project,如下所示:

    ArticleSet x;
    // consider we've found something using `by_db_id` index
    ArticleSet::index_const_iterator<by_db_id>::type it = 
      x.get<by_db_id>().find( SOME_ID );
    
    // convert to default index ( `random_access<>` )
    ArticleSet::const_iterator it1 = x.project<0>( it );
    // iterator_to looks like:
    ArticleSet::const_iterator it11 = x.iterator_to( *it );
    
    // convert to index tagged with `by_title` tag
    ArticleSet::index_const_iterator<by_title>::type it2 = x.project<by_title>( it );
    // iterator_to doen't look better in this case:
    ArticleSet::index_const_iterator<by_title>::type it2 = x.get<by_title>().iterator_to( *it );
    
    // etc.
    

    【讨论】:

    • 是的,这也有效。当我获得新选票时,我会给你 +1 :)
    • +1 我很好奇@Kyrill - 在幕后,这和我的答案似乎都在节点值上使用了make_iterator。有任何理由偏爱其中一个吗?
    • 喜欢这个的一个可能原因是它对用户隐藏了取消引用。不过我不太喜欢&lt;0&gt; 位...
    • @larsman - Boost.MultiIndex 很大程度上基于 TMP - 想想你得到了什么,那小小的丑陋似乎是一个很小的代价。
    • @Steve Townsend,iterator_toBoost 中相对较新的功能(从 1.35 开始就有)。与默认索引一起使用时,它会添加一些语法糖。对于旧版本的Boost,函数project 是唯一的选择。
    【解决方案2】:

    每个索引都支持使用iterator_to 按值生成迭代器。如果您在一个索引中已经有一个指向目标值的迭代器,则可以使用它来转换为另一个索引中的迭代器。

    iterator       iterator_to(const value_type& x);
    const_iterator iterator_to(const value_type& x)const;
    

    对于转换为索引,您可以遵循random_access_index.hpp 中的模型:

      iterator erase(iterator first,iterator last)
      {
        BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(first);
        BOOST_MULTI_INDEX_CHECK_VALID_ITERATOR(last);
        BOOST_MULTI_INDEX_CHECK_IS_OWNER(first,*this);
        BOOST_MULTI_INDEX_CHECK_IS_OWNER(last,*this);
        BOOST_MULTI_INDEX_CHECK_VALID_RANGE(first,last);
        BOOST_MULTI_INDEX_RND_INDEX_CHECK_INVARIANT;
        difference_type n=last-first;
        relocate(end(),first,last);
        while(n--)pop_back();
        return last;
      }
    

    【讨论】:

    • 那么iterator_to(*it) 应该给我一个随机访问迭代器吗?以及如何将其转换为数字索引,因为这是我真正需要的(索引到矩阵中)?
    • @larsman - 从 random_indexed 代码的内部判断,要求是此类索引上的迭代器是可区分的,即。 iter - index.begin() 应该可以工作。见编辑。
    猜你喜欢
    • 2015-04-03
    • 2019-07-26
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    • 2014-09-19
    • 1970-01-01
    相关资源
    最近更新 更多