I would like to create a class that acts as an interface to a set of specialized template classes. For example:
template<typename T>
class ThingDoer {
public:
void Method()
{
// do something;
}
};
class ThingDoerInterface {
public:
template<typename T>
void Method()
{
// call ThingDoer<T>::Method(); somehow
}
};
int main()
{
ThingDoerInterface i;
i.Method<int>();
i.Method<char>();
// etc.
return 0;
}
My generic requirements for the object I’d like look something like this:
- A user needs to only create one, non-templated instance of the object.
- But multiple instances can exist, and are expected to be independent.
- The object associates an instance of an (user-defined) object derived from type A with (one or more) ones derived from type B.
- A user can call a method on the object that does something with B based on the type of A.
I have a working solution to my actual problem that’s based on std::unordered_multimap, but I’m interested if something like this can be done with templates alone.
Edit:
This is a more specific example that I hope will illustrate what I am actually trying to do.
class ABase {
public:
virtual ~ABase() {}
};
class A1 : public ABase {};
class A2 : public ABase {};
class BBase {
public:
virtual ~BBase() {}
};
class B1 : public BBase {};
class B2 : public BBase {};
class ThingDoerInterface {
public:
template<typename T>
void Store(BBase* b_ptr)
{
// store the B pointer with the type of T as a key
// (T will be A1 or A2)
}
template<typename T>
void Recall()
{
// call all the stored B pointers associated with the type of T
}
};
int main()
{
ThingDoerInterface i;
B1* b_one_ptr = new B1;
B2* b_two_ptr = new B2;
i.Store<A1>(b_one_ptr);
i.Store<A1>(b_two_ptr);
i.Store<A2>(b_one_ptr);
i.Recall<A1>(); // do something with b_one_ptr and b_two_ptr
i.Recall<A2>(); // do something with b_one_ptr
delete b_two_ptr;
delete b_one_ptr;
return 0;
}
And I have done this with an std::unordered_multimap, but what I want to know is if it is possible to store the association like this:
template<typename T>
class ThingDoer {
public:
void Store(BBase* b_ptr)
{
b_ptrs.push_back(b_ptr);
}
void Recall()
{
// do something with the b_ptrs associated with the type of T
}
private:
std::vector<BBase*> b_ptrs;
};
but do so in the ThingDoerInterface somehow.
I’m not necessarily saying it’s worth the complexity, but…
I’ve written it for fast lookup. The first time you call get for a given repo, you invalidate all references returned by other repos, and destroying a repo doesn’t clean up anything. But if you have a small number of repos whose lifetime is basically the whole program, that should be ok.