Template Parameter Template with GCC

I try to use the template template as a parameter, everything is fine when I compile with clang, but when I try to use GCC 4.8, I have the following error:

cannot deduce a template for "TReceiver" from a type without a template "DamageAnimationSystem"

Here is my situation: I have a program in which classes can subscribe to the event dispatcher for some types of events, but not for all.

For this, I inherit a class with a specific type:

 class DamageAnimationSystem : public Receiver<DamageEvent>, 
                               public Receiver<HealthEvent>

Here, my class will listen to "DamageEvent" and "HealthEvent", so I need to declare virtual methods for this type of event:

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, everything is fine when I use Clang, but when I use GCC, I got the above error.

:

:

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, clang NDK.

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'

!

+4
1

( ): https://ideone.com/EheCok

:

eventManager.subscribe<HealthEvent, ::Receiver>(this);
eventManager.subscribe<DamageEvent, ::Receiver>(this);
+1

Source: https://habr.com/ru/post/1526026/


All Articles