Sobrecarga de função de membro de modelo e herança múltipla em C++
-
13-12-2019 - |
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.
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()