Reputation: 6395
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?
B*
pointers instead works fine, but then the hashing algorithm of the map compares the pointers, not the objects, which will not find a matchIn 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
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