Student4K
Student4K

Reputation: 951

Compile-time override of given base class methods

Is it possible to conditionally override base methods in derived template class for parameterized base type? I mean, I have different base classes that contain their default method definitions and I would like to define at compile time, which base class I want to use and which methods in that class I want to override, passing something like lambda function, that would be called in overridden implementation. Like:

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 and BaseTwo interfaces are generated by external tool and their interfaces cannot be changed, i.e. their interface methods are polymorphic, cannot depend on particular implementation in derived class, must have the same common base class type (no templates in base classes) and all derivatives of BaseOne are used like with regular polymorphism:

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

Upvotes: 3

Views: 209

Answers (1)

Artyer
Artyer

Reputation: 40791

It would be much easier to implement these as local classes:

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

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

These can use exactly the same things a lambda could have used, and are much clearer, whilst still defined close to where they are used.

Upvotes: 2

Related Questions