首页 > 解决方案 > 给定基类方法的编译时覆盖

问题描述

是否可以有条件地覆盖派生模板类中参数化基类型的基方法?我的意思是,我有不同的基类,其中包含它们的默认方法定义,我想在编译时定义,我想使用哪个基类以及我想覆盖该类中的哪些方法,传递类似 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它们的接口不能改变,即它们的接口方法是多态的,不能依赖于派生类中的特定实现,必须具有相同的公共基类类型(基类中没有模板)和所有派生类ofBaseOne与常规多态性一样使用:

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

标签: c++templatesoverridingcompile-time

解决方案


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

int main()
{
    class : BaseOne
    {
        // default BaseOne::f definition
    } d1;

    class : BaseTwo
    {
        // overridden BaseTwo::g definition
        void g(double& x) override
        {
            x += 2;
        }
    } d2;
}

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


推荐阅读