鉴于以下情况:
#include <iostream>
enum class Event { None, Resize, /*Some Other Events*/ };
template<Event Type, typename...>
struct validator;
template<Event Type>
using eventor = typename validator<Type>::type;
template<>
struct validator<Event::Resize> { using type = void(*)(unsigned int, unsigned int); };
struct My_Event {
unsigned int size;
void** funcs;
const Event &m_ev;
My_Event(const Event &ev, void(*f)(...)) : m_ev(ev), size(1), funcs(new void*[size]) { *funcs = f; }
void reg(void(*f)(...));
};
struct EventHolder {
unsigned int size;
My_Event** events;
EventHolder() : size(0), events((My_Event**)malloc(size)) {}
void add(const Event& ev, void(*f)(...)) {
My_Event** eventDump = (My_Event**)(malloc(size+1));
memcpy(eventDump, events, size);
*(eventDump + size) = new My_Event(ev, f);
free(events);
events = eventDump;
}
};
struct EventRegistry {
EventHolder holder;
void registerEvent(Event&& ev, void(*f)(...)) { holder.add(ev, f); }
} events;
template<Event Type>
void registerEvent(eventor<Type> f) {
events.registerEvent(Type, f);
}
void callback(unsigned int width, unsigned int height) {}
int main() {
registerEvent<Event::Resize>(callback);
}
它抛出了那种错误:
'void foo1(SomeEnum &&,void (__cdecl *)(...))': cannot convert argument 2 from 'void (__cdecl *)(unsigned int,unsigned int)' to 'void (__cdecl *)(...)
(这里的要点是注册main
中显示的事件,My_Event
中有EventHolder
数组
如果我使全局函数registerEvent
成为可变函数,它将强制所有回调变为var variadic,这不是我正在寻找的
如果我将EventRegistry的registerEvent作为可变参数模板,请说
template <typename ...Args> registerEvent(Event&& ev, void(*f)(Args...));
然后EventHolder的add
也应该接受可变参数模板,这会将其转换为:
template <typename ...Args> add(const Event& ev, void(*f)(Args...));
当EventHolder的add
调用new My_Event(ev, f)
时,My_Event
的构造函数也应该是可变的。由于构造函数存储函数本地存储在数组中,整个结构My_Event
应该是可变的 1 ,但如果整个结构是可变参数,那么我可以将它存储在EventHolder
的数组中(存储基类不起作用,因为My_Event
中使用的所有方法也都依赖于模板。
1 写这篇文章时,我意识到这句话是错误的(感谢@Igor评论)。我将所有函数存储在My_Event
中,就像void
指针一样,并使所有成员函数访问列表(包括构造函数)可变参数模板。在这样做之后,我可以创建所有其他函数的可变参数模板,并且编译
这个问题已经解决了。无法接受Igor's answer,因为它是评论,不确定如何将此问题标记为已解决或关闭