c++ - GCC模板参数模板

标签 c++ templates gcc clang

我正在尝试使用模板的模板作为参数,当我用 clang 编译时一切正常,但是当我尝试使用 GCC 4.8 时出现以下错误:

can't deduce a template for 'TReceiver' from non-template type 'DamageAnimationSystem'

这是我的情况:我有一个程序,其中类可以为某些类型的事件订阅事件管理器,但不是全部。

为此,我继承了一个具有特定类型的类:

 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;
};

** 事件管理器 **

////////////////////////////////////////////////////////////
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'

再次感谢!

最佳答案

以下编译(不链接):https://ideone.com/EheCok

我以这种方式明确模板参数:

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

关于c++ - GCC模板参数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21659166/

相关文章:

c++ - Visual C++,Windows 更新接口(interface) (IUpdate) <wuapi.h>,get_MsrcSeverity

c++ - 如何从 C stdio.h getline() 中替换/忽略无效的 Unicode/UTF8 字符?

c# - 我们可以使用 QT 和 C# 来创建 GUI 吗?

GCC 链接器 - 指定存档文件中包含的代码的输出部分

c++ - 使用 malloc 分配比现有内存更多的内存

c++ - 创建模板参数的默认值变量

templates - 使用 Golang 模板如何在每个模板中设置变量?

html - FreeMarker模板中字符串过长如何灵活调整列宽?

c++ - 功能模板的部分属性在 GCC 中被静默忽略

c++ - 使用 -O2 或 -O3 标志编译时未捕获异常