c++templatesinheritanceambiguitypolicy-based-design

Ambiguous inheritance in policy-based design


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

Solution

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

    Live Example