Как сказать C ++ mixin реализуемый интерфейс

У меня есть интерфейс и класс, реализующий его:

class InterfaceA
{
public:
enum Enum { X, Y, Z };
virtual void foo(Enum &) = 0;
virtual void bar() = 0;
};

class ClassA : public InterfaceA
{
public:
virtual void foo(Enum & a) {
a = X;
}
virtual void bar();
};

Мне нужно расширить функциональность класса реализации InterfaceA в одном аспекте. В моем понимании это то, для чего нужны миксины.

Например. foo () должна изменить значение своего параметра при некоторых условиях. Вот как я это делаю:

template <typename T>
class Mixin : public T
{
public:
virtual void foo(Enum & a) {
T::foo(a);
if (a == X){
a = Y;
}
}
};

Проблема в том, что он не скомпилируется, если я не запишу префиксы области для идентификаторов, определенных в классе интерфейса, или не опишу их так:

template <typename T>
class Mixin : public T
{
public:
typedef InterfaceA::Enum Enum;
virtual void foo(Enum & a) {
T::foo(a);
if (a == InterfaceA::X){
a = InterfaceA::Y;
}
}
};

Это не имеет большого значения, если из определения интерфейса мало таких типов. Но если их много, это может стать уродливым. Я хотел бы, чтобы код отражал тот факт, что Mixin манипулирует объектом InterfaceA по своему дизайну. К сожалению, наследование Mixin от InterfaceA представляет «ужасный бриллиант», которого мне лучше избегать. Это возможно?

1

Решение

Enum, X а также Y должно быть зависимое имя.

И вы можете использовать static_assert заставить наследство.

template <typename T>
class Mixin : public T
{
public:
static_assert(std::is_base_of<InterfaceA, T>::value,
"T should inherit from InterfaceA");

virtual void foo(typename T::Enum & a) {
T::foo(a);
if (a == T::X){
a = T::Y;
}
}
};
0

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

Я полагаю, вы должны использовать виртуальное наследование; это должно избежать проблемы «страшного алмаза».

Что-то вроде

class InterfaceA
{
public:
enum Enum { X, Y, Z };
virtual void foo(Enum &) = 0;
virtual void bar() = 0;
};

class ClassA : public virtual InterfaceA
{
public:
virtual void foo(Enum & a) {
a = X;
}
virtual void bar() {
}
};

template <typename T>
class Mixin : public T, public virtual InterfaceA
{
public:
virtual void foo(Enum & a) {
T::foo(a);
if (a == X){
a = Y;
}
}
};int main ()
{
Mixin<ClassA> m;

return 0;
}
0

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