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

Когда я использую статический полиморфизм (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;
};

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

2

Другие решения

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

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

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

0

По вопросам рекламы [email protected]