Reputation: 185
I have a host class, which takes two policies, sayhello
and talk
. The policy talk
is a class template, which itself takes e.g. sayhello
.
The problem is that sayhello::saySomething
is ambiguous in host2
(i tried to solve this diamond problem with virtual
).
How can i resolve this ambiguity? Or is there in general a better design for such problems?
Example:
#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;
}
Upvotes: 2
Views: 214
Reputation: 70526
You are probably abusing inheritance, but just add a couple more virtual
keywords in both talk
and 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;
}
Upvotes: 2
Reputation: 56863
You could add a dummy class:
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();
}
};
In some cases you will probably need to cast to L
directly, which should work like this:
L& getL()
{
return static_cast<L&>(static_cast<dummy<L>&>(*this));
}
Upvotes: 1