【问题标题】:Compile-time override of given base class methods给定基类方法的编译时覆盖
【发布时间】: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
}

编辑: 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 */
}

【问题讨论】:

  • 也许使用std::enable_if_v 或类似方法在两个不同的Derived 类之间进行选择,每个类都继承自两个不同的基类?
  • 很好的问题,你知道 CRTP 吗?
  • @Superlokkus ,有趣,以前没听说过,但刚刚读过。 AFAIU,CRTP 在这里不适用,因为在 CRTP 中基类不同,例如如果我有template&lt;class DerivedT&gt; struct BaseOne 模板和两个不同的实例化BaseOne&lt;Derived1&gt;BaseOne&lt;Derived2&gt;,那么这两个实例化将是没有公共基类的不同类类型。但在我的情况下,Base* 类必须保持虚拟接口。实际上,我无法更改基类,因为它们是由外部工具生成的。
  • 我理解你的意思吗:你不能改变基类?你想用那些派生类实现什么,你想如何使用它们?请将其添加到您的问题中。
  • 是否可以将BaseTwo::g 重命名为f

标签: c++ templates overriding compile-time


【解决方案1】:

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

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

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

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

【讨论】:

  • 优雅,完全忘记了本地类的存在
猜你喜欢
  • 1970-01-01
  • 2012-09-15
  • 2011-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-14
  • 1970-01-01
相关资源
最近更新 更多