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

C++ 给定基类方法的编译时重写,c++,templates,overriding,compile-time,C++,Templates,Overriding,Compile Time,是否可以有条件地重写参数化基类型的派生模板类中的基方法? 我的意思是,我有不同的基类,这些基类包含它们的默认方法定义,我想在编译时定义,我想使用哪个基类,我想覆盖那个类中的哪些方法,传递lambda函数之类的东西,在被覆盖的实现中调用。比如: struct BaseOne { virtual void f(int& x, const int& y) { x += y; } }; struct BaseTwo { virtual v

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

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

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

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

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

也许可以使用
std::enable_if_v
或类似的方法在两个不同的
派生的
类之间进行选择,每个类都继承自两个不同的基类?好问题,你知道CRTP吗?@Superlokkus,很有趣,以前没有听说过,但刚刚读过。另外,CRTP在这里不适用,因为在CRTP中基类是不同的,例如,如果我有
template struct BaseOne
template和两个不同的实例化
BaseOne
BaseOne
,那么这两个实例化将是不同的类类型,没有公共基类。但是在我的例子中,
Base*
类必须保持虚拟接口。事实上,我不能更改基类,因为它们是由外部工具生成的。所以我对您的理解是正确的:您不能更改基类吗?您想用这些派生类实现什么,如何使用它们?请将此添加到您的问题中。是否可以将
BaseTwo::g
重命名为
f
?优雅,完全忘记了本地类的存在
int main()
{
    class : BaseOne
    {
        // default BaseOne::f definition
    } d1;

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