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)
然而,这似乎很混乱,所以我想知道是否有更好的方法.
我认为@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)
你完成了.