Question

J'observe un comportement dans le code ci-dessous que je ne peux pas expliquer facilement et j'aimerais mieux comprendre la théorie.Je n'arrive pas à trouver une source de documentation en ligne ou une question existante qui couvre cette situation particulière.Pour référence, j'utilise Visual Studio C++ 2010 pour compiler et exécuter le code suivant :

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

Pourquoi cela fonctionne-t-il différemment pour la fonction membre basée sur un modèle et pour.cas de fonctions membres non modélisés ?

Comment le compilateur décide-t-il (dans le cas basé sur un modèle) que Top_Class::Print_Goodbye() est la surcharge appropriée plutôt que Bottom_Class::Print_Goodbye() ?

Merci d'avance pour votre considération.

Était-ce utile?

La solution

Dans le Dispatch méthode, This_Type est le même que My_Merged_Class.Le My_Merged_Class a deux méthodes avec les noms de Print_Hello, bien sûr, le compilateur aura du mal à les distinguer.

L'appel à Print_Hello dans Dispatch, après remplacement du modèle, ressemble à ceci :

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

J'espère que la substitution ci-dessus vous aidera à mieux comprendre pourquoi il y a une ambiguïté.Le même problème devrait se produisent réellement pour Print_Goodbye, mais il se peut qu'il s'agisse d'un bug du compilateur que vous utilisez qui le laisse passer.

Autres conseils

Les deux commentaires (AFAIK) génèrent une erreur de compilation avec GCC 4.6.3.Peut-être que le compilateur Microsoft fait quelque chose d'incorrect.

➜  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()

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top