Home > OS >  Easy way to alias base class method (other than constructor) in derived class in C
Easy way to alias base class method (other than constructor) in derived class in C

Time:04-03

I'd like to alias a method of a base class in a derived method in C -- i.e. change only the name, not the signature.

The method's name is clear enough in its original scope (in the base class), but becomes ambiguous or misleading in the derived class. Thus, the obvious mitigation is to create an alias for the method in the base class. However, the long list of parameters the method takes is in flux as the derived class is being refined & retested. I'd like to avoid the boilerplate data entry task of re-typing the method signature, and alias it in a simpler manner, much like I can do with the 'using' directive for an inherited specialized constructor.

Simple example:

struct Person {
    int ID;
    void virtual sit() {};
    void virtual walk() {};
    void virtual run(int speed, int duration, int stride) {}; //method name in unambiguous in this scope

    Person(int id) : ID(id) {}  //specialized c'tor
};

struct Politician : Person {
    void speak() {};
    void campaign() {}; //use this to 'run' for office
    //'sit' and 'walk' are clear enough, but 'run' is ambiguous in this scope, so alias it to 'sprint'
    void sprint(int speed, int duration, int stride) { 
        Person::run(speed, duration, stride);
    }   //the above works, but is a boat-load of boilerplate that I'd like to avoid

    using Person::Person;           //use Person c'tor (avoids boilerplate)
    //using sprint = Person::run;   //doesn't work - "'run' in 'struct Person' does not name a type"
};

(Also consider a virtual class that inherits from multiple base classes, with one or more identically-named base-class methods. Such is my real-world application that I boiled down into this simpler example of the root need.)

Surely there is an easier way to create an alias for an unchanged inherited method, right?

CodePudding user response:

The answer you asked for

template <typename ...T>
decltype(auto) wrapper(T... t)
{
    return func_whos_sig_keeps_changing(t...);
}

The answer you need

You're either violating the primary principal behind inheritance, or have not yet thought through how you intend to use this.

The whole point of inhering from person is so that somewhere in your code you can have this:

std::unique_ptr<person> person_ptr;
...
...
person_ptr->run();

Without caring about what actual type of person it is.
If you can't do this with a politician, then its not a person and shouldn't inherit from person, at least not publicly.

CodePudding user response:

Evidently the answer is: It cannot be done the easy (dynamic & elegant) way. It has to just be 'hard-coded' the way I showed as the example of how I wanted to avoid having to do it. This was proposed for the C standard and rejected because the need was "unlikely to become common enough to warrant a separate language feature," and "not likely to become everyday work for novices."

The proposed syntax to rename/alias an inherited method, adapted to my example, was:

void sprint() = Person::run;

Credit to SO users Max Lybbert and Tomalla for finding it in Design & Evolution of C section 12.8.

  • Related