本文介绍了继承模板方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class similar to the following:

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

        //... other methods etc.
};

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

However, what I really want is to have two different kinds of SomeClass. Ideally, I would be able to derive from a common interface to make SomeOtherClass, but I need to have a different implementation of doSomething and templated methods cannot be virtual. I could make a templated class, but then every method that takes one of these (and there are many) would themselves have to be templates etc.

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

The best I've been able to come up with is to implement both types of doSomething in the base class and have that method call a virtual method to determine which to use at runtime.

有更好的解决方案吗?

I有许多看起来类似的方法:

I have many methods that look similar to this:

void foo(SomeClass * obj);

foo 来电 obj-> doSomething 这一切都运行良好,但我已经意识到我需要一种不同的 SomeClass 但是希望它能够工作使用这些相同的方法,例如:

foo calls obj->doSomething and this all works fine, however I've since realized that I need a different kind of SomeClass but want it to work with these same methods, for example:

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语句分隔,该语句检查实例实际是什么类型:

The above would be ideal, if it were legal, but virtual methods cannot be templated. I've thus far gotten around this limitation by only having doSomething defined in the base class, but with both the implementation for TheFirstType and TheSecondType separated by an if statement that checks on what type the instance actually is:

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
    }
}

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

This seems messy, however, so I was wondering if there is a better way.

推荐答案

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

I think @stijn's answer is correct; you have an ideal case for CRTP. You may choose to alter your logic according to that.

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;
  }
};

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

Now simply inherit these class to your other child classes:

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

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

你已经完成。

这篇关于继承模板方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 11:19