Неоднозначное наследование в политическом дизайне

У меня есть хост-класс, который принимает две политики, sayhello а также talk, Политика talk это шаблон класса, который сам принимает, например, sayhello,
Проблема в том, что sayhello::saySomething неоднозначно в host2 (Я пытался решить эту проблему с алмазом virtual).

Как я могу решить эту двусмысленность? Или есть вообще лучший дизайн для таких проблем?

Пример:

#include <iostream>

class sayhello {
protected:
void saySomething(void) {
std::cout<<"Hello!"<<std::endl;
}
};

template<typename T>
class talk : private T {
protected:
void doSomething(void) {
T::saySomething();
}
};

template<typename T>
class host1 : virtual T {
public:
void hostAction(void) {
T::doSomething();
}
};

template<typename T, typename L>
class host2 : private T, private L {
public:
void hostAction(void) {
T::doSomething();
L::saySomething();
}
};

int main() {
host1<talk<sayhello> > HOST1;
HOST1.hostAction(); // ok that works

host2<talk<sayhello>,sayhello> HOST2;
HOST2.hostAction(); // error, ambiguity!

return 0;
}

2

Решение

Вы, вероятно, злоупотребляете наследованием, но просто добавьте еще пару virtual ключевые слова в обоих talk а также host2:

#include <iostream>

class sayhello {
protected:
void saySomething(void) {
std::cout<<"Hello!"<<std::endl;
}
};

template<typename T>
class talk : virtual T {
protected:
void doSomething(void) {
T::saySomething();
}
};

template<typename T>
class host1 : virtual T {
public:
void hostAction(void) {
T::doSomething();
}
};

template<typename T, typename L>
class host2 : virtual T, virtual L {
public:
void hostAction(void) {
T::doSomething();
L::saySomething();
}
};

int main() {
host1<talk<sayhello> > HOST1;
HOST1.hostAction(); // ok that works

host2<talk<sayhello>,sayhello> HOST2;
HOST2.hostAction(); // error, ambiguity!

return 0;
}

Живой пример

2

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

Вы можете добавить фиктивный класс:

template<typename T> struct dummy : T {};

template<typename T, typename L>
class host2 : private T, private dummy<L> {
public:
void hostAction(void) {
T::doSomething();
dummy<L>::saySomething();
}
};

В некоторых случаях вам, вероятно, нужно будет L напрямую, что должно работать так:

L& getL()
{
return static_cast<L&>(static_cast<dummy<L>&>(*this));
}
1

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