Я получаю следующую ошибку компиляции в одном из моих классов, используя gcc 3.4.5 (mingw):
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&]
Надеюсь, вы видите, что ISource<T>
— это интерфейс шаблона, который просто указывает, что объект может быть информатором для объекта, который относится к некоторому подходящему типу IListener<T>
. Так что меня раздражала идея о том, что по какой-то причине функции неоднозначны, хотя, насколько я могу судить, это не так. Метод addListener()
перегружен для разных типов ввода IListener<const SConsolePacket&>
и IListener<const SControlPacket&>
. Использование:
m_controller->addListener( m_model );
Где m_model
— указатель на объект IRigidBody
, а IRigidBody
наследуется только от IListener< const SControlPacket& >
и определенно не от IListener< const SConsolePacket& >
В качестве проверки работоспособности я использовал doxygen для создания диаграммы иерархии классов, и doxygen согласен со мной, что IRigidBody
не является производным от IListener< const SConsolePacket& >
.
Очевидно, мое понимание наследования в С++ не совсем верно. У меня сложилось впечатление, что IListener<const SControlPacket&>
и IListener<const SConsolePacket&>
- это два разных типа и что объявления функций
addListener(IListener<const SConsolePacket&>* listener)
и
addListener(IListener<const SControlPacket&>* listener)
объявить две отдельные функции, которые выполняют две отдельные функции в зависимости от (отличного) другого типа вводимого параметра. Кроме того, у меня сложилось впечатление, что указатель на IRigidBody
также является указателем на IListener<const SControlPacket&>
и что при вызове addListener( m_model )
компилятор должен понимать, что я вызываю вторую из двух вышеперечисленных функций.
Я даже пробовал приводить m_model
вот так:
m_controller->addListener(
static_cast<IListener<const SControlPacket&>*>(m_model) );
но все равно получаю эту ошибку. Я не могу себе представить, насколько неоднозначны эти функции. Кто-нибудь может пролить свет на этот вопрос?
P.S. Я знаю, как заставить функцию быть однозначной, сделав это:
m_controller->ISource<const SControlPacket&>::addListener( m_model );
Мне просто кажется, что это ужасно нечитабельно, и я бы предпочел не делать этого.
Редактировать... шучу. Очевидно, это не решает проблему, поскольку приводит к ошибке компоновщика:
CModelTesterGui.cpp:1312: undefined reference to `utility::ISource<aerobat::SControlPacket const&>::addListener(utility::IListener<SControlPacket const&>*)'
m_controller->ISource<const SControlPacket&>::addListener( m_model );
устраняет неоднозначность вызова? Если функции перегружены, они должны быть в одном классе. Где объявлены эти функции? - person Johannes Schaub - litb   schedule 21.08.2009