Pregunta

Estoy observando el comportamiento en el siguiente código que no puedo explicar fácilmente y me gustaría comprender mejor la teoría.Parece que no puedo encontrar una fuente de documentación en línea o una pregunta existente que cubra esta situación en particular.Para referencia, estoy usando Visual Studio C ++ 2010 para compilar y ejecutar el siguiente 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 qué funciona esto de manera diferente para la función de miembro de miembro plantelado frente a los casos de función de miembros no plantificados?

¿Cómo decide el compilador (en el caso plantificado) que top_class :: print_goodbye () es la sobrecarga apropiada en lugar de la pantalla de fondo :: imprimir_goodbye ()?

Gracias de antemano por su consideración.

¿Fue útil?

Solución

En el método Dispatch, This_Type es el mismo que My_Merged_Class.El My_Merged_Class tiene dos métodos con los nombres de Print_Hello, por supuesto, el compilador tendrá problemas para distinguir entre ellos.

La llamada a Print_Hello en Dispatch, después del reemplazo de la plantilla, se ve así:

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

Espero que la sustitución anterior le ayude a ver mejor por qué hay una ambigüedad.El mismo problema debería realmente ocurrir para Print_Goodbye, pero podría ser un error en el compilador que está utilizando eso lo permite a través de.

Otros consejos

Ambos comentarios (AFAIK correctamente) generan un error de compilación con GCC 4.6.3.Puede ser el compilador de Microsoft está haciendo algo incorrecto.

➜  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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top