从 Boost 多索引迭代器获取数字索引

发布于 2024-10-02 19:43:26 字数 770 浏览 8 评论 0原文

我将以下一堆内容存储

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 ,一个来自 index< /代码>。在不向 struct Article 中添加数据成员的情况下,将这些索引转换为容器的随机访问部分的最简单方法是什么?

I'm storing a bunch of the following

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

in a Boost.MultiIndex container, defined as

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;

Now I've got two iterators, one from index<by_title> and one from index<by_id>. What is the easiest way to transform these to indexes into the random access part of the container, without adding a data member to struct Article?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

沦落红尘 2024-10-09 19:43:26

每个索引都支持使用 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;
  }

Every index supports generation of an iterator by value using iterator_to. If you already have an iterator to the target value in one index, you could use this to convert to an iterator in another index.

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

For conversion to index you can likely follow the model in 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;
  }
秋凉 2024-10-09 19:43:26

iterator_to< /a> 是 Boost 中相对较新的函数(从 1.35 开始就有)。与默认索引一起使用时,它添加了一些语法糖。对于旧版本的 Boost,函数 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.

iterator_to is a relatively new function in Boost (it's there since 1.35). It adds a little of the syntax sugar when using with default index. For older versions of Boost the function project is the only choise. You can use project as follows:

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文