继承模板方法

Syd*_*ius 9 c++ inheritance templates c++11

我有一个类似于以下的类:

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

        //... other methods etc.
};
Run Code Online (Sandbox Code Playgroud)

但是,我真正想要的是有两种不同的SomeClass.理想情况下,我将能够从一个通用接口派生SomeOtherClass,但我需要有一个不同的实现doSomething和模板化的方法不能是虚拟的.我可以创建一个模板化的类,但是每个采用其中一个(并且有很多)的方法本身都必须是模板等.

我能够想到的最好的doSomething方法是在基类中实现两种类型,并让该方法调用一个虚方法来确定在运行时使用哪种类型.

有更好的解决方案吗?

进一步说明

我有很多方法看起来类似于:

void foo(SomeClass * obj);
Run Code Online (Sandbox Code Playgroud)

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
};
Run Code Online (Sandbox Code Playgroud)

如果它是合法的,上述将是理想的,但虚拟方法不能被模板化.到目前为止,我只是doSomething在基类中定义了这个限制,但是实现TheFirstType和TheSecondTypeif语句分开,它检查实例实际上是什么类型:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,这似乎很混乱,所以我想知道是否有更好的方法.

iam*_*ind 6

我认为@stijn的答案是正确的; 你有一个理想的CRTP案例.你可以选择改变你的逻辑.

template<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;
  }
};
Run Code Online (Sandbox Code Playgroud)

现在只需将这些继承class到您的其他子类:

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

  virtual void foo ()
  {
  }
};   // do same for TheSecondType.
Run Code Online (Sandbox Code Playgroud)

你完成了.

  • 嗯...但是如何声明一个指向`SomeClass`的指针,用于我类似于`void foo(SomeClass*obj)的许多函数;`? (2认同)
  • 这正是我试图避免的,因为它将对我的代码产生连锁反应(因为这些方法的调用者本身必须知道他们正在处理哪些子类并被模板化等).这是一种可能性,我开始认为没有一种好方法可以避免无法使用虚拟模板方法. (2认同)