基于策略的设计中的模糊继承

时间:2013-10-19 22:29:58

标签: c++ templates inheritance ambiguity policy-based-design

我有一个主机类,它采用两个策略sayhellotalk。政策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 个答案:

答案 0 :(得分:2)

您可能滥用继承,但只需在virtualtalk中添加几个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;
}

Live Example

答案 1 :(得分:1)

你可以添加一个虚拟类:

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));
}