Inheritance of template methods

I have a class similar to the following:

class SomeClass
{
    public:
        template<typename... Args>
        void doSomething(Args && ... args);

        //... other methods etc.
};

However, I really want to have two different types SomeClass. Ideally, I could get a common interface for creating SomeOtherClass, but I need to have a different implementation doSomething, and the template methods cannot be virtual. I could make a template class, but then every method that accepts one of them (and there are many of them) must itself be templates, etc.

The best I could come up with was to implement both types doSomethingin the base class and call this method to determine the virtual method that will be used at runtime.

Is there a better solution?

Further explanation

I have many methods that look something like this:

void foo(SomeClass * obj);

foo obj->doSomething, , , SomeClass, , , :

class SomeClass
{
    public:
        // This won't work
        template<typename... Args>
        virtual void doSomething(Args && ... args) = 0;

        // ... other common methods
};

class TheFirstType
{
    public:
        template<typename... Args>
        void doSomething(Args && ... args);

        // ... other specific methods
};

class TheSecondType
{
    public:
        template<typename... Args>
        void doSomething(Args && ... args);

        // ... other specific methods
};

, , . , doSomething, , TheFirstType TheSecondType, if, , :

template<typename... Args>
void SomeClass::doSomething(Args && ... args)
{
    if (this->type() == FIRST_TYPE) {
        // ... the implementation that should rightfully be part of TheFirstType
    } else if (this->type() == SECOND_TYPE) {
        // ... the implementation that should be part of TheSecondType
    }
}

, , , .

+5
2

, @stijn ; CRTP. .

typename<class T>
class SomeClass
{
public:
  template<typename... Args>
  void doSomething(Args && ... args)
  {
    static_cast<T*>(this)->doSomething(...);
  }
  //other method can be virtual
  virtual void foo ()
  {
    doSomething(...);
    // ... other code;
  }
};

class :

class TheFirstType : SomeClass<TheFirstType>
{
public:
  template<typename... Args>
  void doSomething(Args && ... args) { ... }

  virtual void foo ()
  {
  }
};   // do same for TheSecondType.

.

+2

, CRTP ( , iammilind ):

template< class Parent >
class SomeClassBase : public Parent
{
public:
  //common methods go here
};

class SomeClass : public SomeClassBase< SomeClass >
{
public:
  template<typename... Args>
  void doSomething(Args && ... args);
};

class SomeOtherClass : public SomeClassBase< SomeOtherClass >
{
public:
  template<typename... Args>
  void doSomething(Args && ... args);
};
+1

All Articles