gpt4 book ai didi

C++ : create custom function dispatcher from variadic template

转载 作者:太空狗 更新时间:2023-10-29 20:04:35 25 4
gpt4 key购买 nike

我有一些函数可以从序列化数据中读取各种类型,例如:

class DataDeserializer
{
int getInt();
std::string getString();
MyClass getMyClass();
}

然后我有各种带有任意参数的回调函数,例如:

void callbackA (int, int, int);
void callbackB (int, std::string);
void callbackC (std::string, int, MyClass, int);

我想使用从反序列化数据流中读取的参数调用各种回调。我想要的是尽可能自动化样板代码。我在想也许我可以使用模板。如果我有某种调度程序类,例如:

template <SOMETHING??> class Dispatcher
{
void dispatch()
{
// ????
}

SOMEFUNCTIONTYPE callback;
DataDeserializer myDeserializer;
};

然后声明各种具体的调度器:

Dispatcher<int,int,int>                  myDispatcherA (deserializer, callbackA);
Dispatcher<int,std::string> myDispatcherB (deserializer, callbackB);
Dispatcher<std::string,int,MyClass,int> myDispatcherC (deserializer, callbackC);

然后当我想调度时,我只需调用:

myDispatcherB.dispatch();

下面会扩展成这样:

void dispatch()
{
callback (myDeserializer.getString(), myDeserializer.getInt(), myDeserializer.getMyClass(), myDeserializer.getInt());
}

C++11 可变参数模板是否可行?我已经阅读了一些关于它们的内容,递归似乎用得很多。

最佳答案

我为我的 stream_function 做了类似的事情类(class)。基本思想是将类型传递给执行 The Right Thing™ 的函数模板,然后扩展该调用:

callback(magic<Args>(/* sth */)...);

但是,如果您的函数不是纯函数并且修改了某些状态,并且因此要求它们需要以正确的顺序调用,则您必须使用一些技巧来强制执行该顺序。

如果您使用的是 Clang,这会相当容易,因为它会强制对大括号初始化列表进行从左到右的求值。这允许您只使用一个小的助手类型

struct invoker{
template<class F, class... Args>
invoker(F&& f, Args&&... args){ f(std::forward<Args>(args)...); }
};

然后做

invoker{ callback, magic<Args>(/* sth */)... };

不幸的是,GCC 尚未实现此功能,因此需要求助于手动命令执行。这可以通过一个小的辅助结构来完成,它只是一个类型列表,但允许做一些有用的事情:

  • 查看包何时为空(types<>),以及
  • 进程Args以先头后尾的递归方式

template<class...> struct types{};

template<class... Args>
struct dispatcher{
std::function<void(Args...)> f;

void call(){ _call(types<Args...>{}); }
private:
// take head, produce value from it, pass after other values
template<class Head, class... Tail, class... Vs>
void _call(types<Head, Tail...>, Vs&&... vs){
_call(types<Tail...>{}, std::forward<Vs>(vs)..., get_value<Head>());
}

// no more values to produce, forward to callback function
template<class... Vs>
void _call(types<>, Vs&&... vs){ f(std::forward<Vs>(vs)...); }
};

Live example.

关于C++ : create custom function dispatcher from variadic template,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18847424/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com