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.

+3


source to share


1 answer


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) { .. }

      

+5


source







All Articles