Переопределение во время компиляции данных методов базового класса - PullRequest
3 голосов
/ 11 июля 2019

Можно ли условно переопределить базовые методы в производном шаблонном классе для параметризованного базового типа? Я имею в виду, у меня есть разные базовые классы, которые содержат их определения методов по умолчанию, и я хотел бы определить во время компиляции, какой базовый класс я хочу использовать и какие методы в этом классе я хочу переопределить, передавая что-то вроде лямбда-функции, которая бы вызываться в переопределенной реализации. Как:

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
}

Edit: BaseOne и BaseTwo интерфейсы генерируются внешним инструментом, и их интерфейсы не могут быть изменены, т.е. их методы интерфейса полиморфны, не могут зависеть от конкретной реализации в производном классе, должны иметь одинаковый общий тип базового класса (в базовых классах нет шаблонов) ) и все производные 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 Ответ

2 голосов
/ 12 июля 2019

Было бы намного проще реализовать их как локальные классы:

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

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

Они могут использовать те же самые вещи, что и лямбда, и намного более понятны, хотя все еще определены близко к тому месту, где они находятся.б.

...