Suppose that I have a Foo class like this, and I need many instances of it.
class Foo {
public:
Pool* bars; // a global list of bars, each may have a different type
template<typename T>
T& AddBar(int x) {
return bars->emplace<T>(x);
}
template<typename T>
T& GetBar() {
return bars->get<T>(); // a very slow function
}
}
All the instances of Foo share the same pool of bars, which contains many bars of possibly different types. For example, bars may be a list of bars {A bar1, B bar2, A bar3, C bar4} where ABC are some class types, but each Foo foo instance can only have one bar of a specific type, e.g., a foo instance cannot have two bars of type A.
Given an instance Foo foo, I can get a specific type of bar using foo.GetBar<A>(), foo.GetBar<B>(), etc, but calling the bars->get<T>() function is slow and expensive. Therefore, I'm thinking of caching the result of GetBar() so that subsequent calls can return immediately without querying the pool again.
Now this is what I came up with: I created a static variable inside the member function to store the value of bar, it is only initialized and assigned value once.
template<typename T>
T& GetBar() {
static T bar {};
if (bar == T {}) {
bar = bars->get<T>(); // a very slow function
}
return bar;
}
The problem is that, using the static keyword, this variable is now shared across all instances of Foo. If I try to get a bar of type A from different instances, they would return the same result.
Foo foo1;
Foo foo2;
foo1.AddBar<A>(1);
foo2.AddBar<A>(2);
foo1.GetBar<A>(); // returns a bar (type = A, value = 1)
foo2.GetBar<A>(); // returns the same bar with value 1, not 2
How can I cache every bar of type T inside the class and prevent it from being shared by other instances? I don't know how to store generic types as member variables, besides, storing each type T of bar can be a huge mess.
Edit: I know it'd be much easier to cache the result outside the class, on the caller's side. I'm just curious if there's an elegant way of caching inside the class.
Edit2: bars is a pointer to a registry pool, whose type is a complicated data structure, not a raw list or array. To clarify, I'm using the EnTT library to integrate entity-component-system into my application, but not sure how the pool is maintained internally in details.
Edit3: if you wonder what ABCs are, conceptually, these types are not known at compile time. but need to be determined at runtime. In fact, they are just many other class types I implemented, so I can also hardcode them into the Foo class, in which case I probably should use the factory pattern along with a scripting language for automatic code generation, but that would beat the purpose of using generics in the first place.