That again is not a good design. Can you explain your problem in more detail so that I can offer suggestions (maybe not practical as you know your use case better than me) that may be more valid?
So the problem that I trying to solve initially.
I want to have instances of custom types (called "components") be bound to one or more ids (called "entities"), in a way that a user can bind any type of component to any entity (entity can have 0 or more components, but can't have more than one component of the same type). So basically it is a custom ECS.
User should be able to iterate over sets of components bound to entities that have them.
E.g. I want to iterate over all the entities that have components Movement and Transform, I do
entityManager.forEachComponentSet<Movement, Transform>([](Movement* movement, Transform* transform)
{
transform->x += movement->speedPerTickX;
transform->y += movement->speedPerTickY;
});
This will move all the entities that have both components by one step to a direction determined by "movement".
So, to be able to do that right now I store components of one type in a vector of void* (they are constructed/destructed using an abstract factory, so the user doesn't need to care about the details, they just need to make sure a component is default constructible and that they didn't forget to call registerComponent<MyComponent>() on the factory).
Then I store these vectors mapped by the component type (which is just an ID type, the details don't matter much here), I store them in an unordered_map right now (key is the ID, value is a vector<void*>).
And then when I want to get them back, I want to get components from these vectors, using some matching logic.
Then right now I'm building a kind of index/cache to have a bit less indirections when iterating over components. I want to store them as tuples of pointers (I have another type of index already, but I want to see if reducing amount of indirections changes anything with how fast it goes on the benchmarks).
It is mostly an educational thing, there are already implementations that do mostly what I want, but I want to be able to reason about these things not just assume how it behaves.