Aganju
Aganju

Reputation: 6395

How to build a Map where the Key is an abstract base class (not Value)

I am trying to build a map of objects that are instances of various derived classes, with the base class being abstract:

class B {void SomeMethod() = 0;}; //abstract
class D1 : public B {...}; // not abstract
class D2 : public B {...}; // not abstract
std::unordered_map<B,int> myMap;

D1 * d1 = new D1();
D2 * d2 = new D2();
myMap.insert({*d1,5}
myMap.insert({*d2,8}

That does not work, because the map considers *d1 a B object, and tries to copy-construct it inside the map. even if it would work, it would slice the object, and the D1-data would be lost. So far I understand why it can't work.

But how can I make such a map?

In other words, the Question is:
How can I build a map of objects (and later search for them), where these objects are instances of different derived classes from a common base class?

Upvotes: 2

Views: 881

Answers (1)

Rakete1111
Rakete1111

Reputation: 48938

Yeah, your second option is not possible. But your first is! Standard library containers let you use a custom hashing function, which you can use to your advantage.

Also, you would have needed to provide a custom hash function anyways, so it's shouldn't be an issue. Also you mentioned you wanted to be able to search them right? Well, the standard library also allows you to customize that too and you can provide a key equality object which would compare the underlying objects and not the pointers.

struct FooPtrHash {
  std::size_t operator()(const Foo *Value) const {
    return Value->Value;
  }
};

struct FooPtrEquality {
  bool operator()(const Foo *Lhs, const Foo *Rhs) const {
    return *Lhs == *Rhs;
  }
};

std::unordered_map<Foo*, int, FooPtrHash, FooPtrEquality> Map;

Upvotes: 1

Related Questions