I'm trying to use template of template as parameter, everything is ok when I compile with clang but when I try with GCC 4.8 I have the following error:
can't deduce a template for 'TReceiver' from non-template type 'DamageAnimationSystem'
Here is my situation: I've got a program where classes can subscribe to the event manager for some type of events but not all.
To do that, I inherit from a class with a specific type:
class DamageAnimationSystem : public Receiver<DamageEvent>,
public Receiver<HealthEvent>
Here, my class will listen "DamageEvent" and "HealthEvent" so I need to declare virtual methods for this type of events:
DamageAnimationSystem::onEvent( const DamageEvent& event ) {}
DamageAnimationSystem::onEvent( const HealthEvent& event ) {}
And I need to subscribe to this event:
DamageAnimationSystem::DamageAnimationSystem()
{
eventManager->subscribe<DamageEvent>(this);
eventManager->subscribe<HealthEvent>(this);
}
As I said before, everything is ok when I use Clang but when I use GCC I've got the error given above.
Here is what I've done:
Receiver:
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;
};
Event:
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);
}
I've made the simulation online to test result : https://ideone.com/vZZhqN
Thanks a lot for your help!
PS: I need compatibility with GCC because I need to use this code with android NDK and thread didn't work with clang on last NDK.
I'm trying to use another method with std::function and std::bind:
Receiver:
class Receiver {};
Event:
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));
}
I've got the following error on 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'
Thanks again!
The following compiles (don't link): https://ideone.com/EheCok
I explicit the template argument that way:
eventManager.subscribe<HealthEvent, ::Receiver>(this);
eventManager.subscribe<DamageEvent, ::Receiver>(this);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With