使用键属性向量提升多索引

Boost multiindex with vector of keys attribute

我有一个 class 看起来像这样(简化):

class DataObject {
public:
    int getId() const;
    const std::vector<int>& getAccounts() const;
};

我需要一个由 id 及其适用的所有帐户索引的对象的关联数组(散列图)。 IE。我需要查找适用于特定帐户的所有 DataObject 个实例(而单个 DataObject 可以适用于多个帐户)。

我首先想到的是使用 boost::multi_index_contatiner 来索引两者。但是,我不知道如何为该对象创建所有帐户的索引,我不确定这是否可行。

我开始的是这样的:

struct tags
{
    struct id;
    struct account;
};

typedef boost::multi_index_container<
    const DataObject*,
    boost::multi_index::indexed_by<
        // index by the rule id (replacement, removal)
        boost::multi_index::hashed_unique<
            boost::multi_index::tag<tags::id>,
            boost::multi_index::const_mem_fun<DataObject, int, &DataObject::getId>
        >,
        // index by the account
        boost::multi_index::hashed_non_unique<
            boost::multi_index::tag<tags::account>,
            ???
        >
    >
> DataMap_t;

而且我不知道应该用什么代替 ??? 来提取单个特定帐户。回顾一下,我 不想按帐户的矢量 进行索引(我知道该怎么做),我需要按 中的每个帐户进行索引矢量.

到目前为止,我实际上为 ID 创建了一个单独的 boost::unordered_map<int, const DataObject*> 索引,为帐户创建了另一个单独的 boost::unordered_multimap<int, const DataObject*> 索引,然后我遍历所有帐户并为每个帐户存储一个值(以及删除相同)。但我想知道是否有更简单的方法,最好使用 boost::multi_index_container.

你需要的是关系table。

您也可以使用 Boost Bimap(对我来说似乎更容易):

The following code creates an empty bimap container:

typedef bimap<X,Y> bm_type; 
bm_type bm; 

Given this code, the following is the complete description of the resulting bimap.

  • bm.left is signature-compatible with std::map
  • bm.right is signature-compatible with std::map
  • bm is signature-compatible with std::set< relation >

使用多索引我建议将关系存储在对象之外:

struct Data { int id; };
struct Account { int id; };

struct Relation { int data_id, account_id; };

using Table = boost::multi_index_container<Relation, 
    bmi::indexed_by<
        bmi::ordered_unique<
            bmi::tag<struct by_data>,
            bmi::member<Relation, int, &Relation::data_id>
        >
        bmi::ordered_non_unique<
            bmi::tag<struct by_account>,
            bmi::member<Relation, int, &Relation::account_id>
        >
    >
>;

如果您注意对象的生命周期和引用稳定性,您可以更方便调用者:

struct Data { int id; };
struct Account { int id; };

struct Relation { 
    std::reference_wrapper<Data const> data;
    std::reference_wrapper<Account const> account;

    int data_id() const    { return data.get().id; }
    int account_id() const { return account.get().id; }
};

using Table = boost::multi_index_container<Relation, 
    bmi::indexed_by<
        bmi::ordered_unique<
            bmi::tag<struct by_data>,
            bmi::const_mem_fun<Relation, int, &Relation::data_id>
        >
        bmi::ordered_non_unique<
            bmi::tag<struct by_account>,
            bmi::const_mem_fun<Relation, int, &Relation::account_id>
        >
    >
>;