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

