You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++非类型模板参数使用报错,如何为Event类正确传递事件类型参数

错误原因
  • 主模板参数声明不匹配:你当前的Event主模板仅接受类型参数包template<class...Args>,但你期望第一个模板参数是int类型的非类型参数(用来传递事件类型值),编译器在实例化时看到你传了整数值90,而主模板期望接收类型,因此直接抛出类型不匹配错误。
  • 偏特化语法错误:你写的偏特化声明template<int eventType,class...Args> class Event<int eventType, bool(Args...)>不符合C++语法规则,偏特化的参数列表要和主模板的参数顺序、类别严格对应。
修复方案
  1. 先修改主模板的参数列表,明确第一个参数为int类型的非类型参数,第二个参数为函数签名类型:
// 修改前:template<class...Args> class Event : public IEvent {};
template<int eventType, class FuncSig>
class Event : public IEvent {};
  1. 修正偏特化的声明,匹配主模板的参数结构:
// 修改前:template<int eventType,class...Args> class Event<int eventType, bool(Args...)> : public IEvent
template<int eventType, class...Args>
class Event<eventType, bool(Args...)> : public IEvent

其他业务逻辑不需要改动,修改后你的实例化代码Event<90,bool(bool, double)> evnt(&w, &Window::OnKeyUp);就可以正常编译运行。

完整可运行代码
#include <stdio.h>
#include <iostream>
#include <functional>
#include <vector>
using namespace std;

class IEvent
{
public:
    int m_EventType;
    virtual ~IEvent() {}
};

// 修正后的主模板:第一个参数为int类型非类型参数,第二个为函数签名类型
template<int eventType, class FuncSig>
class Event : public IEvent {};

// 修正后的偏特化:匹配函数签名为bool(Args...)的场景
template<int eventType,class...Args>
class Event<eventType, bool(Args...)> : public IEvent
{
public:
    Event(bool(*func)(Args...)) :m_FnPtr(func)
    { 
         m_EventType = eventType;
         m_ListenersList.push_back(m_FnPtr);
    }

    template <typename T>
    Event(T* obj, bool(T::* Func)(Args...))
    {
        m_EventType = eventType;
        m_FnPtr = [obj, Func](Args&&... args)->bool {
            return (obj->*Func)(std::forward<Args>(args)...);
        };
        
        m_ListenersList.push_back(m_FnPtr);
    }

    void NotifyListeners(Args&&...args) const
    {
        for (auto& itr : m_ListenersList)
        {
            (itr)(std::forward<Args>(args)...);
        }
    }
private:
    std::function<bool(Args...)> m_FnPtr;
    std::vector<std::function<bool(Args...)>> m_ListenersList; 
};

class Window
{
public:
    bool OnKeyUp(bool, double)
    {
        cout << endl << "Member Function called";
        return true;
    }

    bool OnClicked()
    {
        cout << endl << "OnClicked";
        return true;
    }
};

int main()
{
    Window w;
    Event<90,bool(bool, double)> evnt(&w, &Window::OnKeyUp);
    evnt.NotifyListeners(true, 6.8);
    return 0;
}

内容的提问来源于stack exchange,提问作者Akshay R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 12:24:01