Статический полиморфизм и имена методов C++

Когда я использую статический полиморфизм (CRTP), есть ли хороший способ дать полиморфным методам их имена?

template <class Derived> 
struct Base
{
    void interface()
    {
        // ...
        static_cast<Derived*>(this)->implementation();
        // ...
    }

    static void static_func()
    {
        // ...
        Derived::static_sub_func();
        // ...
    }
};

struct Derived : Base<Derived>
{
    void implementation();
    static void static_sub_func();
};

Потому что, насколько я знаю, интерфейс и реализация не могут иметь одно и то же имя (как если бы они были виртуальными). И это немного неловко, если иерархия классов глубока.

Может быть, есть какой-то хороший способ справиться с этим? А может я просто ошибаюсь?

2 ответа

Мой подход заключается в том, чтобы избежать наследования (как это ни странно) и использовать вместо этого агрегирование. Шаблон класса предоставляет интерфейс, а в свою очередь предоставляет класс делегата с реализацией. Это будет выглядеть примерно так:

template <class Delegate>
struct Interface
{
    void do_something()
    {
        // ...
        delegate.do_something();
        // ...
    }

    Delegate delegate;
};

Это имеет тот недостаток, что неудобнее предоставлять аргументы конструктора для объекта делегата, но это не слишком сложно для управления.

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

Однако в вашем случае кажется, что вы хотите, чтобы родитель выполнил некоторую работу до и после вызова виртуального метода (пахнет как шаблон шаблона). В этом случае, независимо от того, используете ли вы полиморфизм времени выполнения (виртуальный) или время компиляции (CRTP), вам придется вызывать интерфейс и методы реализации по альтернативным именам.

Если foo это метод интерфейса / шаблона в базе, то do_foo или же foo_impl кажутся совершенно разумными именами для функций реализации независимо от времени выполнения или полиморфизма времени компиляции.

Другие вопросы по тегам