Member initialization based on a template, where the template is derived from an abstract class
I am working on an implementation of a genetic algorithm that should work on an abstract genome type.
My setup looks something like this:
class AbstractGenome
{
virtual void init() = 0;
virtual void mutate() = 0;
.
.
.
};
class GeneticAlgorithm
{
std::vector<AbstractGenome*> genomes;
void init(int numGenomes)
{
for (int i=0; i < numGenomes; ++i)
{
AbstractGenome *genome = new DerivedGenome(); <=This is where my problem is
genome->init();
genomes.push_back(genome);
}
}
}
where DerivedGenome should be defined later (at some point) as:
class DerivedGenome: public AbstractGenome
{
void init() { do stuff; }
void mutate() {do stuff; }
}
My problem is that the only thing I know about DerivedGenome is that it comes from AbstractGenome - so I cannot make a generic call to DerivedGenome's constructor.
One way I can work out is to extract from GeneticAlgorithm and override the init function for all genome types, but I was wondering if there was a better way to solve this, for example using templates?
Many thanks.
source to share
You can pass the type DerivedGenome
to init()
:
template <typename Derived>
void init(int numGenomes)
{
for (int i=0; i < numGenomes; ++i)
{
AbstractGenome *genome = new Derived();
genome->init();
genomes.push_back(genome);
}
}
with which you can call via:
init<DerivedGenome>(42);
If you want a more explicit compilation error in case you try to execute init<int>(5)
, you can change the return type to require inheritance:
template <typename Derived>
typename std::enable_if<
std::is_base_of<AbstractGenome, Derived>::value
>::type init(int numGenomes) { .. }
source to share