0

I need to override the method createT() of a Base template class with the one in a Derived template class with a different number of input parameters. I've developed this very simple example:

#include <iostream>

class Helper
{
public:
  Helper(std::string s): _s(s)
  {}

  void display()
  {
     std::cout << _s << std::endl;
  }

private:
  std::string _s;
};

class Helper2
{
public:
  Helper2(std::string s, int i):
    _s(s), _i(i)
  {}

  void display()
  {
    std::cout << _s << " + " << std::to_string(_i) << std::endl;
  }

private:
  std::string _s;
  int _i;
};

template<class T> class Base
{
public:
  Base()
  {
    _pTBase = createT();
  }

  void test()
  {
    _pTBase->display();
  }

protected:
  /// Subclasses can override this method.
  virtual T* createT()
  {
    return new T("### BASE ###");
  }

private:
 T* _pTBase;

}; //template<class T> class Base


template<class T> class Derived : public Base<T>
{
public:
  Derived() : Base<T>()
  {
    _pTDerived = createT();
  }

  void test()
  {
    _pTDerived->display();
  }

protected:
  virtual T* createT()
  {
    return new T("### DERIVED ###", 5);
  }

private:

 T* _pTDerived;

}; //template<class T> class Derived : public Base<T>


int main()
{
  Derived<Helper2> a;

  a.test();

  return 0;
}

When I try to compile I receive this message:

error: no matching function for call to ‘Helper2::Helper2(const char [13])’
     return new T("### BASE ###");
                                ^

It seems that the compiler cannot use the createT() method in the derived class.

Of course everything works correctly if I use the Base class with the Helper (not the Helper2) class.

What's the right way to solve this situation?

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
MarioG
  • 1

1 Answers1

2

When a is constructed, first the Base<Helper2> base object is constructed. That constructor will call Base::createT, which requires Helper2 to have a constructor that takes one parameter. Since that doesn't exist, you get the compilation error.

When you construct a Derived<Helper> object, you get two Helper objects created: one by Base's constructor, stored in _pTBase, and one by Derived<Helper>'s constructor, stored in _pTDerived.

One way to fix this is to have the derived class call a (non-virtual) Create function, then pass the returned pointer to the base class constructor.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Thank you for your reply. The problem is that the **Base** class is part of an external library that I cannot modify and overriding the method **Base::createT** is the only way to use it. – MarioG Oct 27 '18 at 09:08
  • If this is the case, then its unlikely they are expecting you to overide a virtual function that they call in the base constructor. What is the external library? – rmawatson Oct 27 '18 at 12:28
  • Tha external library is POCO. The problem was also shown by @chris [here](https://stackoverflow.com/questions/51872709/poco-custom-socketacceptor) but he hasn't received a response yet. – MarioG Oct 27 '18 at 21:36