У меня есть базовый класс источника событий, который определяет функцию для добавления слушателей, и я пытаюсь использовать аргумент шаблона для устранения неоднозначности. Но это, похоже, не работает — он всегда использует функцию из первого базового класса, а затем жалуется, что параметры шаблона не совпадают:
#include <type_traits>
template<class Event>
class EventSource
{
public:
class Listener
{
public:
virtual void handle( const Event& e ) = 0;
};
template<class EventType>
typename std::enable_if<std::is_same<Event, EventType>::value, void>::type
addListener( Listener* ptr );
};
class Event1 {};
class Event2 {};
class MultiListener : public EventSource<Event1>::Listener, public EventSource<Event2>::Listener
{
public:
void handle( const Event1& e );
void handle( const Event2& e );
};
class MultiSource : public EventSource<Event1>, public EventSource<Event2>
{
public:
void addMultiListener( MultiListener* ptr )
{
addListener<Event1>( ptr );
addListener<Event2>( ptr ); // this line causes error
}
};
Почему это не подпадает под SFINAE?
Я знаю, что могу явно указать базовый класс, но шаблоны выглядят намного лучше, чем EventSource<Event1>::addListener(...)
,
Обе строки вызывают ошибку, так как поиск имени неоднозначен (перед проверкой, являются ли перегрузки жизнеспособными).
Вы можете решить проблему с помощью using
class MultiSource : public EventSource<Event1>, public EventSource<Event2>
{
using EventSource<Event1>::addListener;
using EventSource<Event2>::addListener;
public:
void addMultiListener( MultiListener* ptr )
{
addListener<Event1>( ptr );
addListener<Event2>( ptr );
}
};
Других решений пока нет …