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.
In the Dispatch
method, This_Type
is the same as My_Merged_Class
. The My_Merged_Class
has two methods with the names of Print_Hello
, of course the compiler is going to have problems to distinguish between them.
The call to Print_Hello
in Dispatch
, after template replacement, looks like this:
((My_Merged_Class*)this)->Print_Hello();
I hope the above substitution helps you see better why there is an ambiguity. The same problem should actually occur for Print_Goodbye
, but it might be a bug in the compiler you are using that lets it through.