简体   繁体   中英

C++ - how to create a multimap with 4 variables and 4 keys

I want to create a class like below

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;

I referred boost::multiIndex. But I don't think that it helps on this case. Can anybody say the way to achieve this?

EDIT I am not that much good in reading template classes. As for as I am concerning I didn't find any "find" methods in multiIndex. I saw only sorting out things in that example(the first basic example: link ). Suggestions&advices are always welcomed

boost multiindex is exactly what you need in this case. Construct four indexes for the four keys - I guess given you guarantee that they will all be unique, make them unique indexes (I believe only one of them can be hashed_unique, but I think you can make the other three ordered_unique), and then do your searches on the each index depending on what you are searching by.

Here's a simple example using 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
}

Tag classes could be used to access the indices by name rather than ordinal index as well, usage of which would look like this:

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*/);
}

The difference between the two approaches is purely aesthetic, and of course the tag classes could be named whatever you want rather than byMsdnEnum , etc. Also note that hashed indices could be used rather than ordered indices, which would give your indices the behavior of std::unordered_map rather than std::map .

Is there a reason why you cannot use 2 maps? ( std::map< int, std::string> ). If you need to find both of the string variables by any of those two keys, then you could solve it by having a map that would pair for example msdnEnum with both strings and then have a map that would pair localEnum with msdnEnum . Than any lookup via msdnEnum would be done directly and a lookup via localEnum would first do a translation to msdnEnum and then do a direct lookup.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM