Перегрузка функций-членов шаблона и множественное наследование в C++

StackOverflow https://stackoverflow.com//questions/11697061

Вопрос

Я наблюдаю поведение в приведенном ниже коде, которое не могу легко объяснить, и хотел бы лучше понять теорию.Кажется, я не могу найти источник онлайн-документации или существующий вопрос, который охватывает эту конкретную ситуацию.Для справки: я использую Visual Studio C++ 2010 для компиляции и запуска следующего кода:

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

Почему это работает по-разному для шаблонной функции-члена и для шаблонной функции-члена?случаи нешаблонных функций-членов?

Как компилятор решает (в шаблонном случае), что Top_Class::Print_Goodbye() является подходящей перегрузкой, а не Bottom_Class::Print_Goodbye() ?

Заранее благодарим вас за внимание.

Это было полезно?

Решение

в Dispatch метод, This_Type такой же как My_Merged_ClassMy_Merged_Class имеет два методы с именами Print_Hello, конечно, у компилятора возникнут проблемы с их различием.

Звонок в Print_Hello в Dispatch, после замены шаблона, выглядит так:

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

Я надеюсь, что приведенная выше замена поможет вам лучше понять, почему существует двусмысленность.Та же проблема должен на самом деле происходят для Print_Goodbye, но это может быть ошибка в используемом вами компиляторе, которая позволяет это сделать.

Другие советы

Оба комментария (AFAIK правильно) генерируют ошибку компиляции с GCC 4.6.3.Может быть, компилятор Microsoft делает что-то неправильное.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top