我正在使用可变参数模板来捕获原子组播库(isis2.codeplex.com)Isis2中的静态类型信息。一些Isis2事件通过upcall传递。例如,如果你编码
Group g("myGroup");
g.Handlers[UDPATE] += [](string& name, Foo& f) { ... your code };
....
g.OrderedSend(UPDATE, "John Doe", new Foo(...));
然后在接收组g的组播中携带带有字符串和Foo对象的更新时,Isis2将构造Foo对象的本地实例,然后使用适当的参数向上调用该lambda。
所以这是我的谜题。我有可变参数扫描OrderedSend的参数,并可以捕获构建我的消息所需的静态类型信息。我最终将真正的OrderedSend方法传递给一维参数数组,每个参数都有它的类型,指针或对数据或对象的安全引用,对于一个对象,它是编组方法的地址。但是要使用可变参数模板来扫描lambda,我需要查看函数的“内部参数列表”,从某种意义上说,添加到处理程序向量的对象是一个lambda:type_traits方法只会说它是“函数”类型的对象。我是在lambda的参数列表中的字符串和Foo类型之后。但是就我所见,type_traits.h缺少访问参数列表的任何东西。
GCC-11特定选项是解开typeid并解析生成的字符串。但是有一个可变参数模板功能可以让我在编译时到达lambda的参数列表吗?
答案 0 :(得分:1)
template<class Sig>
struct MessageName {
std::string name;
MessageName() = delete;
MessageName( std::string o ):name(o) {}
MessageName(MessageName&&)=default;
MessageName(MessageName const&)=default;
MessageName& operator=(MessageName&&)=default;
MessageName& operator=(MessageName const&)=default;
};
// trait to determine if some args are compatible:
template<class Sig, class...Ts>
struct is_compatible : std::false_type {};
template<>
struct is_compatible<void()> : std::true_type {};
template<class A0, class...Args, class T0, class...Ts>
struct is_compatible<void(A0, Args...), T0, Ts...>:
std::integral_constant<bool,
std::is_convertible<T0, A0>::value
&& is_compatible< void(Args...), Ts... >::value
>
{};
struct HandlerMap {
template<class Sig>
void add_handler(
MessageName<Sig> msg,
block_deduction< std::function<Sig> > handler
)
{
// ...
}
template<class Sig, class...Ts>
typename std::enable_if<is_compatible<Sig, Ts...>::value>::type
send_message( MessageName<Sig> msg, Ts&&... ts )
{
// ...
}
};
UPDATE
令牌应为MessageName
类型。所有MessageName
s 必须声明与其关联的签名。
MessageName< void(std::string const&, Foo const&) > UPDATE{"update"};
如上所述。
然后,当您添加处理程序时,对add_handler
的调用将根据所需签名检查分配的函数,并为您提供std::function
。
同样,当您发送消息时,可以根据签名检查传递的类型。您甚至应该将参数转换为函数体中每个签名的参数类型。
这会尽可能多地调整类型,以便编译时间,这是很好的C ++风格。
答案 1 :(得分:0)
这是一个简单的例子:
struct fun {
int i;
void operator()(int x) {}
void operator()(float x) {}
};
关于这个结构或它的任何参数都没有超级复杂或非POD。