Pergunta

Estou observando um comportamento no código abaixo que não consigo explicar prontamente e gostaria de entender melhor a teoria.Não consigo encontrar uma fonte de documentação on-line ou uma pergunta existente que cubra esta situação específica.Para referência, estou usando o Visual Studio C++ 2010 para compilar e executar o seguinte código:

#include <iostream>
using namespace std;

struct Bottom_Class
{
    template<typename This_Type>
    void Dispatch()
    {
        // A: When this comment is removed, the program does not compile
        //    citing an ambiguous call to Print_Hello
        // ((This_Type*)this)->Print_Hello();

        // B: When this comment is removed instead, the program compiles and
        //    generates the following output:
        //    >> "Goodbye from Top Class!"
        // ((This_Type*)this)->Print_Goodbye<void>();
    }

    void Print_Hello() {cout << "Hello from Bottom Class!" << endl;}

    template<typename This_Type>
    void Print_Goodbye() {cout << "Goodbye from Bottom Class!" << endl;}
};

struct Top_Class
{
    void Print_Hello() {cout << "Hello from Top Class!" << endl;}

    template<typename This_Type>
    void Print_Goodbye() {cout << "Goodbye from Top Class!" << endl;}
};

template<typename Top_Type,typename Bottom_Type>
struct Merged_Class : public Top_Type, public Bottom_Type {};

typedef Merged_Class<Top_Class,Bottom_Class> My_Merged_Class;

void main()
{
    My_Merged_Class my_merged_object;

    my_merged_object.Dispatch<My_Merged_Class>();
}

Por que isso funciona de maneira diferente para a função de membro modelada vs.casos de função de membro não modelados?

Como o compilador decide (no caso do modelo) que Top_Class::Print_Goodbye() é a sobrecarga apropriada em vez de Bottom_Class::Print_Goodbye() ?

Agradeço antecipadamente por sua consideração.

Foi útil?

Solução

No Dispatch método, This_Type é o mesmo que My_Merged_Class.O My_Merged_Class tem dois métodos com os nomes de Print_Hello, é claro que o compilador terá problemas para distingui-los.

A chamada para Print_Hello em Dispatch, após a substituição do modelo, fica assim:

((My_Merged_Class*)this)->Print_Hello();

Espero que a substituição acima ajude você a ver melhor por que existe uma ambigüidade.O mesmo problema deve realmente ocorre para Print_Goodbye, mas pode ser um bug no compilador que você está usando que permite a passagem.

Outras dicas

Ambos os comentários (AFAIK corretamente) geram erro de compilação com GCC 4.6.3.Pode ser que o compilador da Microsoft esteja fazendo algo incorreto.

➜  scratch  g++ -O2 templ.cc
templ.cc: In member function ‘void Bottom_Class::Dispatch() [with This_Type = Merged_Class<Top_Class, Bottom_Class>]’:
templ.cc:42:48:   instantiated from here
templ.cc:16:9: error: request for member ‘Print_Goodbye’ is ambiguous
templ.cc:22:10: error: candidates are: template<class This_Type> void Bottom_Class::Print_Goodbye()
templ.cc:30:10: error:                 template<class This_Type> void Top_Class::Print_Goodbye()
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top