我正在尝试使用模板模板作为参数,当我使用clang进行编译时一切正常但是当我尝试使用GCC 4.8时出现以下错误:
无法从非模板类型'DamageAnimationSystem'中推断出'TReceiver'的模板
以下是我的情况:我有一个程序,其中类可以为某些类型的事件订阅事件管理器,但不是全部。
为此,我从具有特定类型的类继承:
class DamageAnimationSystem : public Receiver<DamageEvent>,
public Receiver<HealthEvent>
在这里,我的类将侦听“DamageEvent”和“HealthEvent”,因此我需要为此类事件声明虚拟方法:
DamageAnimationSystem::onEvent( const DamageEvent& event ) {}
DamageAnimationSystem::onEvent( const HealthEvent& event ) {}
我需要订阅此活动:
DamageAnimationSystem::DamageAnimationSystem()
{
eventManager->subscribe<DamageEvent>(this);
eventManager->subscribe<HealthEvent>(this);
}
正如我之前所说的,当我使用Clang时一切正常,但是当我使用GCC时,我得到了上面给出的错误。
以下是我所做的:
接收器:
class EBaseReceiver
{
protected:
static std::size_t nextId;
};
template <typename TEventData>
class Receiver : public EBaseReceiver
{
friend class EventManager;
public:
virtual void onEventReceive( const TEventData& event ) = 0;
static std::size_t getId() { return ID; }
private:
static std::size_t ID;
};
事件:
struct BaseEvent
{
protected:
static std::size_t nextId;
};
template <typename T>
struct Event : public BaseEvent
{
static std::size_t getId() { return ID; }
static std::size_t ID;
};
**And finally the event manager:**
template< class TEvent, template<class> class TReceiver>
void EventManager::subscribe( TReceiver<TEvent>* receiver );
{
const std::size_t eventId = TEvent::getId();
this->subscribers[eventId].push_back(receiver);
}
我已在线模拟测试结果:https://ideone.com/vZZhqN
非常感谢你的帮助!
PS:我需要与GCC兼容,因为我需要在Android NDK中使用此代码,并且线程在最后一个NDK上不能与clang一起使用。我正在尝试使用std :: function和std :: bind:
的另一种方法接收器:
class Receiver {};
事件:
template <typename T>
struct Event : public BaseEvent
{
friend class EventManager;
static std::size_t getId() { return ID; }
private:
typedef std::function<void( const T& event )> EventCallback;
static std::size_t ID;
static std::vector<EventCallback> listeners;
};
** EventManager **
////////////////////////////////////////////////////////////
template <typename TEvent>
void emit( const TEvent& event )
{
const auto& listeners = TEvent::listeners;
for( const auto& listener : listeners )
listener(event);
}
////////////////////////////////////////////////////////////
template< class TEvent, class TReceiver>
void subscribe( TReceiver* receiver )
{
TEvent::listeners.push_back(std::bind( &TReceiver::onEventReceive, receiver, std::placeholders::_1));
}
我在std :: bind上遇到以下错误:
No matching function for call to 'bind'
Candidate template ignored: couldn't infer template argument '_Fp'
Candidate template ignored: couldn't infer template argument '_Rp'
再次感谢!
答案 0 :(得分:1)
以下编译(不要链接):https://ideone.com/EheCok
我以这种方式明确了模板参数:
eventManager.subscribe<HealthEvent, ::Receiver>(this);
eventManager.subscribe<DamageEvent, ::Receiver>(this);