Dostaję następujący błąd kompilacji w jednej z moich klas, używając gcc 3.4.5 (MinGW):żądanie członka `...” jest niejednoznaczny w g ++
src/ModelTester/CModelTesterGui.cpp:1308: error: request for member `addListener' is ambiguous
include/utility/ISource.h:26: error: candidates are: void utility::ISource<T>::addListener(utility::IListener<T>*) [with T = const SConsolePacket&]
include/utility/ISource.h:26: error: void utility::ISource<T>::addListener(utility::IListener<T>*) [with T = const SControlPacket&]
Mam nadzieję, że widać, że ISource<T>
to interfejs szablonu, który po prostu wskazuje, że obiekt może być informatorem dla obiektu o pasującym typie: IListener<T>
. Więc to, co mnie irytuje, polega na tym, że z jakiegoś powodu funkcje są niejednoznaczne, o ile mogę to stwierdzić, nie są. Metoda addListener()
jest przeciążona dla różnych typów wejść IListener<const SConsolePacket&>
i IListener<const SControlPacket&>
. Użycie jest:
m_controller->addListener(m_model);
Gdzie m_model
jest wskaźnikiem do obiektu IRigidBody
i IRigidBody
dziedziczy tylko z IListener< const SControlPacket& >
i na pewno nie z IListener< const SConsolePacket& >
Jako kontrola poprawności, użyłem doxygen wygenerować diagram hierarchii klas i doxygen zgadza się ze mną, że IRigidBody
nie wywodzi się z IListener< const SConsolePacket& >
Oczywiście moje rozumienie dziedziczenia w C++ nie jest dokładnie poprawne. Jestem pod wrażeniem, że IListener<const SControlPacket&>
i IListener<const SConsolePacket&>
są dwa różne typy i że deklaracje funkcji
addListener(IListener<const SConsolePacket&>* listener)
i
addListener(IListener<const SControlPacket&>* listener)
zadeklarować dwie odrębne funkcje, które wykonują dwie odrębne rzeczy w zależności od (odrębny) inny typ wprowadzanego parametru. Co więcej, jestem pod wrażeniem, że wskaźnik do IRigidBody
jest również wskaźnikiem do IListener<const SControlPacket&>
i że wywołując addListener(m_model)
kompilator powinien zrozumieć, że wywołuję drugą z powyższych dwóch funkcji.
Próbowałem nawet odlewania m_model
tak:
m_controller->addListener(
static_cast<IListener<const SControlPacket&>*>(m_model));
ale wciąż dostać ten błąd. Nie mogę dla życia mnie zobaczyć, jak te funkcje są niejednoznaczne. Czy ktoś może rzucić światło na ten problem?
P.S. Wiem, jak zmusić funkcję być un-niejednoznaczne w ten sposób:
m_controller->ISource<const SControlPacket&>::addListener(m_model);
ja akurat uważam, że jest strasznie unreadible i wolałbym nie musieć tego robić.
Edytuj ... tylko żartuję. Że widocznie nie rozwiąże problemu, ponieważ prowadzi do błędu łącznikowej:
CModelTesterGui.cpp:1312: undefined reference to `utility::ISource<aerobat::SControlPacket const&>::addListener(utility::IListener<SControlPacket const&>*)'
Jaki jest związek między SControlPacket a SConsolePacket? – GRB
Czy możesz dodać, dlaczego ostatni wiersz 'm_controller-> ISource :: addListener (m_model);" disambiguates the call? Jeśli funkcje są przeciążone, powinny należeć do tej samej klasy. Gdzie są zadeklarowane te funkcje? –
@GRB Brak związku. Oba są strukturami wywodzącymi się z niczego. @litb Myliłem się co do tego. Zmusiło go do kompilacji, ale okazało się, że prowadziło to do błędu łącza, gdy linker jedzie, aby znaleźć ISource <...> :: addListener (...), który jest czysty wirtualny. Teraz jestem bardzo zdezorientowany. Kiedy mówisz oświadczyłeś, że zakładam, że masz na myśli zdefiniowane. Są one zdefiniowane w klasach wydzielonych, które pochodzą od IController. – cheshirekow