C ++ - как создать мультикарту с 4 переменными и 4 ключами - PullRequest
0 голосов
/ 01 марта 2011

Я хочу создать класс, как показано ниже

class enumClass
{
    int msdnEnum;
    std::string msdnEnumString; 
    int localEnum;
    std::string localEnumString;
}

std::set<enumClass_Objects> enums; // all msdnEnums are unique, same aplies to other three.

enums.find(given_msdnEnum)->FourthVariable;
enums.find(given_localEnum)->FirstVariable;
enums.find(given_msdnEnumStr)->anyVariable;
enums.find(given_localEnumStr)->anyVariable;

Я упомянул boost :: multiIndex.Но я не думаю, что это поможет в этом деле.Кто-нибудь может сказать, как этого добиться?

РЕДАКТИРОВАТЬ Я не очень хорош в чтении шаблонов классов.Что касается меня, я не нашел никаких методов поиска в multiIndex.Я видел только сортировку вещей в этом примере (первый базовый пример: ссылка ).Предложения и советы всегда приветствуются

Ответы [ 3 ]

4 голосов
/ 01 марта 2011

boost multiindex - это именно то, что вам нужно в этом случае.Создайте четыре индекса для четырех ключей - я полагаю, если дать вам гарантию, что все они будут уникальными, сделайте их уникальными индексами (я полагаю, что только один из них может быть hashed_unique, но я думаю, что вы можете сделать остальные три order_unique), а затем выполнитеВаши поиски по каждому индексу в зависимости от того, по чему вы ищете.

3 голосов
/ 01 марта 2011

Вот простой пример использования boost.multi_index:

#include <string>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>

struct enumClass
{
  int msdnEnum;
  std::string msdnEnumString; 
  int localEnum;
  std::string localEnumString;
};

namespace bmi = boost::multi_index;

typedef bmi::multi_index_container<
  enumClass,
  bmi::indexed_by<
    bmi::ordered_unique<bmi::member<enumClass, int, &enumClass::msdnEnum> >,
    bmi::ordered_unique<bmi::member<enumClass, std::string, &enumClass::msdnEnumString> >,
    bmi::ordered_unique<bmi::member<enumClass, int, &enumClass::localEnum> >,
    bmi::ordered_unique<bmi::member<enumClass, std::string, &enumClass::localEnumString> >
  >
> enumClassSet;

int main()
{
  enumClassSet enums;
  enums.get<0>().find(/*given_msdnEnum*/);     // index 0 is enumClass::msdnEnum
  enums.get<1>().find(/*given_msdnEnumStr*/);  // index 1 is enumClass::msdnEnumString
  enums.get<2>().find(/*given_localEnum*/);    // index 2 is enumClass::localEnum
  enums.get<3>().find(/*given_localEnumStr*/); // index 3 is enumClass::localEnumString
}

Классы тегов можно использовать для доступа к индексам по имени, а не по порядковому индексу, использование которого будет выглядеть следующим образом:

struct byMsdnEnum;
struct byMsdnEnumStr;
struct byLocalEnum;
struct byLocalEnumStr;

typedef bmi::multi_index_container<
  enumClass,
  bmi::indexed_by<
    bmi::ordered_unique<bmi::tag<byMsdnEnum>, bmi::member<enumClass, int, &enumClass::msdnEnum> >,
    bmi::ordered_unique<bmi::tag<byMsdnEnumStr>, bmi::member<enumClass, std::string, &enumClass::msdnEnumString> >,
    bmi::ordered_unique<bmi::tag<byLocalEnum>, bmi::member<enumClass, int, &enumClass::localEnum> >,
    bmi::ordered_unique<bmi::tag<byLocalEnumStr>, bmi::member<enumClass, std::string, &enumClass::localEnumString> >
  >
> enumClassSet;

int main()
{
  enumClassSet enums;
  enums.get<byMsdnEnum>().find(/*given_msdnEnum*/);
  enums.get<byMsdnEnumStr>().find(/*given_msdnEnumStr*/);
  enums.get<byLocalEnum>().find(/*given_localEnum*/);
  enums.get<byLocalEnumStr>().find(/*given_localEnumString*/);
}

Разница между этими двумя подходами является чисто эстетической, и, конечно, классы тегов могут быть названы как угодно, а не byMsdnEnum и т. Д. Также обратите внимание, что можно использовать хешированные индексы, а не упорядоченные индексы, которыедаст вашим индексам поведение std::unordered_map, а не std::map.

0 голосов
/ 01 марта 2011

Есть ли причина, по которой вы не можете использовать 2 карты?(std :: map ).Если вам нужно найти обе строковые переменные по любому из этих двух ключей, то вы можете решить эту проблему, имея карту, которая будет соединять, например, msdnEnum с обеими строками, а затем иметь карту, которая будет соединять localEnum с msdnEnum.Тогда любой поиск через msdnEnum будет выполнен напрямую, а поиск через localEnum сначала сделает перевод в msdnEnum, а затем выполнит прямой поиск.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...