Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template Member Function Overloading and Multiple Inheritance in C++

I am observing behavior in the below code which I cannot readily explain and would like to understand the theory of better. I cannot seem to find an online documentation source or existing question which covers this particular situation. For reference, I am using Visual Studio C++ 2010 to compile and run the following code:

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

Why does this work differently for the templated member function vs. non-templated member function cases ?

How does the compiler decide (in the templated case) that Top_Class::Print_Goodbye() is the appropriate overload rather than Bottom_Class::Print_Goodbye() ?

Thank you in advance for your consideration.

like image 472
excogitus Avatar asked Jun 27 '26 10:06

excogitus


1 Answers

Both comments (AFAIK correctly) generate compilation error with GCC 4.6.3. May be the Microsoft compiler is doing something 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()
like image 178
parry Avatar answered Jun 29 '26 01:06

parry