0

Is there a way to override a function returning a templated entity with different constructors in C++?

template<T> class A {
  virtual shared_ptr<T> createEntity (a)
     return make_shared<T>(a);
}

class E
{
  int a,b;
  E (int x, int y) : a(x), b(y);
}

class B : public A<E> {
  int b;
  shared_ptr<E> createEntity (a) override 
     return make_shared<E>(a,b);
}

The standard constructor of most Entities would require only one variable, whereas entities of other classes need more than one variable to be constructed. Can this be achieved without conditional compilation?

Edit: Other Entities implement their constructor with only one variable "a", so I basically want to use A::createEntity (a) in most cases and want to use B::createEntitiy in special cases.

Klickmann
  • 130
  • 8
  • You would like `::createEntity` to be shadowed or overridden by `::B::createEntity`? Do I get it correctly? – YSC Mar 11 '20 at 11:58
  • 2
    How would you call this overrided function *via a base class pointer*? If you wouldn't, then inheritance and virtual functions are wrong tools for the job. – n. m. could be an AI Mar 11 '20 at 12:07
  • 1
    You can make the method pure virtual. Then it would be completely up to the derived class to create the T in whatever manner it chooses. As written, the template class A must commit to constructing the T, which means that all of the possible T's must be written in a way that A can construct it. – Raymond Chen Mar 11 '20 at 12:57
  • I guess he wants 'b' argument to be discarded in case E constructor has only a single argument. – darune Mar 11 '20 at 13:09
  • @YSC yes i basically want to shadow the function – Klickmann Mar 11 '20 at 13:14
  • Using [CRTP](https://stackoverflow.com/questions/4173254/what-is-the-curiously-recurring-template-pattern-crtp) with a base class is basically pointless since each specialization of the base class is inherited by exactly one derived type. There is no polymorphism possible. It's a red flag that your design probably won't work. Try to store any kind of `A` in a container and you will see that you can't. – François Andrieux Mar 11 '20 at 13:14

1 Answers1

0

This is fairly easy to achieve (and without conditional compilation even).

All you need to do is to invent a parameters structure of some kind and roll all your arguments into that.

Something like:

struct InitInfo {
  int x_;
  int y_;//may not always be used..
};

Then use it with E:

class E
{
  int a,b;
  public:
  E (InitInfo info) : a(info.x_), b(info.y_) {
  }
};

And used like this:

return make_shared<E>(InitInfo{a,b});
darune
  • 10,480
  • 2
  • 24
  • 62