Home > database >  Using class member as key in a std::map of said class
Using class member as key in a std::map of said class

Time:09-22

I have a class with an enum class member variable which is intended to be used as a description of the instantiated object, there will never be two instantiated objects of the same type, example:

class A
{
   enum class Type { Type1, Type2, ...} type;
}

I want to store all instantiated objects within a collection for easy access based on the type, so I think that a map would be suitable:

class B
{
   std::map<A::Type, A> components;
}

However, something tells me this is not great design because I am effectively duplicating the same data, i.e. using a class (A) member variable (type) as a key that points to a value (object of class A) that also holds the same information. The other alternative would be not to use the enum as a class A member variable but define that enum within class B and only using it as a key. Any advice?

CodePudding user response:

Lets consider the key features of the map

  • unique keys
  • ordererd with respect to keys
  • keys are const, values not
  • key are stored seperately from the mapped values

Your requirement is in contrast with the last bullet so now you can consider what compromise you can make with the others.

  • std::set<A,CustomComparator>

With a custom comparator you can ensure unique keys that can be stored in the values and sorting can be the same as with the map. But elements are const. You could use mutable but this bypasses const-correctness and should be used with care.

  • std::vector<A>

This is the most flexible but you need to take care of almost everything you got from the map manually. It can be feasible if you populate the vector only once and then only access elements, because then you need to check for uniqueness and sort the elements only once.

  • some non-std container

Jarod42 suggested boosts intrusive set. There might be other non-standard containers that fit your needs.

  • just stay with std::map<A::type,A>

If the key is only a single enum value, then storing the keys twice is an easy solution that has some cost, but allows you to use a map when that is the container you want to use.

  • Not store the keys in the mapped_values in the first place

This is actually the cleanest solution when the mapped_values are only stored in the map and not used outside of the map. And when you still need the mapped_values together with the keys outside of the map you can use std::pair<type::A,A>.

  • Related