将可变参数模板转换为可变参数函数

时间:2018-01-21 00:41:15

标签: c++ c++11 c++14 variadic-templates variadic-functions

鉴于以下情况:

#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,因为它是评论,不确定如何将此问题标记为已解决或关闭

0 个答案:

没有答案