【发布时间】:2019-11-21 00:45:34
【问题描述】:
是否可以在派生模板类中为参数化基类型有条件地覆盖基方法? 我的意思是,我有不同的基类,其中包含它们的默认方法定义,我想在编译时定义,我想使用哪个基类以及我想覆盖该类中的哪些方法,传递类似 lambda 函数的东西,这将在重写的实现中被调用。喜欢:
struct BaseOne
{
virtual void f(int& x, const int& y)
{
x += y;
}
};
struct BaseTwo
{
virtual void g(double& x)
{
x += 1.0;
}
};
template<class BaseT/*, method m signature and ID, CallbackT callback*/>
struct Derived: public BaseT
{
/* <mID>(mSignature)> = override
{
callback(<mSignatureArgs...>);
}
*/
// Such that here I do not have to define all methods from BaseT, that could potentially be requested to be overridden at compile-time
};
int main()
{
Derived<BaseOne> d1; // default BaseOne::f definition
Derived<BaseTwo, /* method g, [](double& x) { x += 2; } */> d2; // overridden BaseTwo::g definition
}
编辑:
BaseOne和BaseTwo接口是由外部工具生成的,它们的接口不能改变,即它们的接口方法是多态的,不能依赖于派生类中的特定实现,必须具有相同的公共基类类型(基类中没有模板) 和BaseOne 的所有派生词都与常规多态性一样使用:
void doSomethingWithOnes(BaseOne& one)
{
int x = /* get some x */;
int y = /* get some y */;
one.g(x, y); // this call must be virtual
/* use x and y somehow */
}
【问题讨论】:
-
也许使用
std::enable_if_v或类似方法在两个不同的Derived类之间进行选择,每个类都继承自两个不同的基类? -
很好的问题,你知道 CRTP 吗?
-
@Superlokkus ,有趣,以前没听说过,但刚刚读过。 AFAIU,CRTP 在这里不适用,因为在 CRTP 中基类不同,例如如果我有
template<class DerivedT> struct BaseOne模板和两个不同的实例化BaseOne<Derived1>和BaseOne<Derived2>,那么这两个实例化将是没有公共基类的不同类类型。但在我的情况下,Base*类必须保持虚拟接口。实际上,我无法更改基类,因为它们是由外部工具生成的。 -
我理解你的意思吗:你不能改变基类?你想用那些派生类实现什么,你想如何使用它们?请将其添加到您的问题中。
-
是否可以将
BaseTwo::g重命名为f?
标签: c++ templates overriding compile-time