给定基类方法的编译时覆盖

时间:2019-07-11 10:10:12

标签: c++ templates overriding compile-time

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

1 个答案:

答案 0 :(得分:2)

将它们实现为本地类会容易得多:

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

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

这些可以使用lambda可以使用的完全相同的东西,并且更加清晰,同时仍在接近它们使用的地方进行定义。