Reputation: 10379
I am writing a class framework in C++, packaged into a static library (.lib
). In that library I have a template class Foo
, something like this:
template <class T> class Foo {
<T> data;
}
The framework creates objects of Foo
with a template type that is read from a file. In theory that could look like this:
int
int
float
double
So the framework would load the text file, and based on that it would instantiate the class Foo
four times, with template types int
, int
, float
, double
.
So far this works fine. Now to the tricky part: The client application (that uses the framework in .lib
) can derive a custom class from Foo
, let's call it Bar
. Now I need to allow that custom class in the config text file, like this:
int
int
Bar
Which would mean that the framework should create two Foo<int>
objects, and one instance of Bar
. Is something like that possible in C++, so that the framework would dynamically instantiate a class that the client application defines?
If that is not possible, what would be the appropriate solution to this in C++?
Upvotes: 0
Views: 174
Reputation: 509
Suppose you have a fixed set of possible types for the template parameter T
, say int
, float
, and double
.
Then you could have the following functions in your framework API:
registerFactory(std::function<std::unique_ptr<Foo<int>>()> f);
registerFactory(std::function<std::unique_ptr<Foo<float>>()> f);
registerFactory(std::function<std::unique_ptr<Foo<double>>()> f);
The client application can now call one or more of the registerFactory
functions, passing a function which creates a pointer to a Foo
object, for example
template<typename T> class Bar : public Foo<T> { ... };
std::unique_ptr<Foo<int>> createBar() { return std::make_unique<Bar<int>>(); }
framework.registerFactory(createBar);
The framework would store the std::function
objects, e.g. in std::vector
s (one for each template parameter type).
On some init()
function (also part of the framework API), the framework would go through its config file and create the Foo<>
objects as before and in addition it would go through the registered factory functions and call them.
Upvotes: 1