2015-09-30 4 views
1

Я новый для увеличения несколько индексов контейнера, и был интересен, если он может решить более эффективным способом моей проблемы, упрощенный таким образом:Повысьте Мульти индекс: индекс на основе содержимого списка

struct A { 
    int id; 
} 

struct B { 
    int id; 
    std::list<A> products; 
} 

Каждого A, имеющими строго уникальный идентификатор, я хочу иметь возможность с одним контейнером с несколькими индексами, иметь возможность искать B. Идентификатором B и идентификатором A.

В настоящий момент я работаю с красивой std :: map и привязкой к карте. Идентификаторы к идентификаторам B. Так сказать. Он работает достаточно хорошо. Но, у меня другие параметры для такого взгляда вверх, и это становится действительно противный :)

EDIT:

Согласно комментарию просьбе я разработать несколько:

Я сателлиты, которые в свою очередь, много транспондеров и многих источников. Я хочу, чтобы найти спутник для данного идентификатора транспондера или идентификатор источника (которые действительно уникальны)

К сожалению, у меня нет руки на спутниковой структуре, значит, я не могу ее изменить.

Вкратце это выглядит так:

struct Satellite { 
int norad_id; 
std::list<Transponder> transponders; 
std::list<Source> sources; 
... some more data 
} 

То, что я хочу сделать, это просто поискаШлюпку независимо от спутников, и найти спутник, имеющую удельную transponder- или source- или NORAD идентификатор.

На данный момент я использую 3 красивые карты

std::map<int /*norad*/ ,Satellite> satellites; 
std::map<int /*transponder id*/, int/* norad */> transponder_to_satellite; 
std::map<int /* source_id */, int /* norad */ > source_to_satellite; 

Из примера @sehe при условии, я вижу, что это будет несколько проще, если бы я икра relationnal структуры. Я предполагаю, что я дам ему попробовать ... :)

+0

Вы должны сделать образец реальной. Как было сказано, мультимапа или бимапа будет много. «Но у меня есть другие параметры для такого поиска» (что?). Быть конкретной.Кроме того, попробуйте не указывать имена типов, потому что это сделает невозможным выявление основной проблемы XY. – sehe

ответ

1

В absense точных случаев использования, вот некоторые предложения для моделирования индексов, основанных на том, что вы showed¹

struct Product { 
int id; 
}; 

struct Category { 
int id; 
}; 

struct ProductCategoryRelation { 
    int productId; 
    int categoryId; 
}; 

namespace bmi = boost::multi_index; 

using RelationTable = bmi::multi_index_container< 
    ProductCategoryRelation, 
    bmi::indexed_by< 
     bmi::ordered_unique< 
      bmi::tag<struct by_product>, 
      bmi::member<ProductCategoryRelation, int, &ProductCategoryRelation::productId> 
     >, 
     bmi::ordered_unique< 
      bmi::tag<struct by_category>, 
      bmi::member<ProductCategoryRelation, int, &ProductCategoryRelation::categoryId> 
     > 
    > 
>; 

Вы можете также получить довольно умный с составным ключом, который является универсальным в ordered_* индексов:

using RelationTable = bmi::multi_index_container< 
    ProductCategoryRelation, 
    bmi::indexed_by< 
     bmi::ordered_unique< 
      bmi::tag<struct by_product>, 
      bmi::composite_key<ProductCategoryRelation, 
       bmi::member<ProductCategoryRelation, int, &ProductCategoryRelation::categoryId>, 
       bmi::member<ProductCategoryRelation, int, &ProductCategoryRelation::productId> 
      > 
     > 
    > 
>; 

Вот небольшой демо:

Live On Coliru

#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/member.hpp> 
#include <boost/multi_index/mem_fun.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/hashed_index.hpp> 
#include <boost/multi_index/composite_key.hpp> 
#include <boost/multi_index/global_fun.hpp> 
#include <list> 

struct Product { 
    int id; 
}; 

struct Category { 
    int id; 
}; 

struct ProductCategoryRelation { 
    int productId; 
    int categoryId; 
}; 

namespace bmi = boost::multi_index; 

using RelationTable = bmi::multi_index_container< 
    ProductCategoryRelation, 
    bmi::indexed_by< 
     bmi::ordered_unique< 
      bmi::tag<struct compound>, 
      bmi::composite_key<ProductCategoryRelation, 
       bmi::member<ProductCategoryRelation, int, &ProductCategoryRelation::categoryId>, 
       bmi::member<ProductCategoryRelation, int, &ProductCategoryRelation::productId> 
      > 
     > 
    > 
>; 

#include <iostream> 
#include <boost/range/iterator_range.hpp> 

int main() { 
    RelationTable table { 
     ProductCategoryRelation { 1, 7 }, 
     ProductCategoryRelation { 2, 7 }, 
     ProductCategoryRelation { 3, 7 }, 
     ProductCategoryRelation { 4, 6 }, 
     ProductCategoryRelation { 5, 6 }, 
     ProductCategoryRelation { 6, 6 }, 
     ProductCategoryRelation { 7, 5 }, 
     ProductCategoryRelation { 8, 5 }, 
     ProductCategoryRelation { 9, 5 }, 
    }; 

    // find all products in category 6: 
    for (auto& rel : boost::make_iterator_range(table.get<compound>().equal_range(6))) 
     std::cout << "Product " << rel.productId << " is in category " << rel.categoryId << "\n"; 
} 

Печать:

Product 4 is in category 6 
Product 5 is in category 6 
Product 6 is in category 6 

¹ I кристалл-сжались имена классов во что-то "реалистической"

+0

Отредактированный мой вопрос, я благодарю вас за этот пример, я попробую, но, как сказано в моем редактировании, m не разрешено редактировать исходную структуру. Это усложняет реализацию этой стратегии. – Kluthen57

Смежные вопросы