给定基类方法的编译时重写

Compile-time override of given base class methods

本文关键字:编译 重写 类方法 基类      更新时间:2023-10-16

是否可以有条件地重写参数化基类型的派生模板类中的基方法?我的意思是,我有不同的基类,其中包含它们的默认方法定义,我想在编译时定义我想要使用哪个基类以及我想要覆盖该类中的哪些方法,传递类似 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
}

编辑: BaseOneBaseTwo接口由外部工具生成,它们的接口不能更改,即它们的接口方法是多态的,不能依赖于派生类中的特定实现,必须具有相同的公共基类类型(基类中没有模板(,并且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 */
}

将这些实现为本地类要容易得多:

int main()
{
    class : BaseOne
    {
        // default BaseOne::f definition
    } d1;
    class : BaseTwo
    {
        // overridden BaseTwo::g definition
        void g(double& x) override
        {
            x += 2;
        }
    } d2;
}

这些可以使用与lambda完全相同的东西,并且更清晰,同时仍然定义接近它们的使用位置。