C ++ 11: Desambiguar membro da classe em herança múltipla

Suponha que eu tenho esse modelo de classe base variável:

template <typename ... Types>
class Base
{
public:
    // The member foo() can only be called when its template 
    // parameter is contained within the Types ... pack.

    template <typename T>
    typename std::enable_if<Contains<T, Types ...>::value>::type
    foo() {
        std::cout << "Base::foo()\n";
    }
};

ofoo() membro só pode ser chamado quando seu parâmetro de modelo corresponde a pelo menos um dos parâmetros deBase (A implementação deContains está listado na parte inferior deste post):

Base<int, char>().foo<int>(); // fine
Base<int, char>().foo<void>(); // error

Agora eu defino uma classe derivada que herda duas vezes de Base, usandoconjuntos sem sobreposição dos tipos:

struct Derived: public Base<int, char>,
                public Base<double, void>
{};

Eu esperava que ao ligar, por exemplo,

Derived().foo<int>();

o compilador descobriria qual classe base usar, porque é SFINAE fora daquela que não contémint. No entanto, o GCC 4.9 e o Clang 3.5 reclamam de uma chamada ambígua.

Minha pergunta então é dupla:

Por que o compilador não pode resolver essa ambiguidade (interesse geral)?O que posso fazer para fazer isso funcionar, sem precisar escreverDerived().Base<int, char>::foo<int>();? EDITAR: GuyGreer me mostrou que a chamada não é ambígua quando adiciono duas declarações de uso. No entanto, como estou fornecendo a classe base para a herança do usuário, essa não é a solução ideal. Se possível, não quero que meus usuários adicionem essas declarações (que podem ser bastante detalhadas e repetitivas para grandes listas de tipos) às classes derivadas.

Implementação deContains:

template <typename T, typename ... Pack>
struct Contains;

template <typename T>
struct Contains<T>: public std::false_type
{};

template <typename T, typename ... Pack>
struct Contains<T, T, Pack ...>: public std::true_type
{};

template <typename T, typename U, typename ... Pack>
struct Contains<T, U, Pack ...>: public Contains<T, Pack...>
{};

questionAnswers(2)

yourAnswerToTheQuestion