我使用各种模板来捕获Isis2中的静态类型信息,这是一个原子多播库(isis2.codeplex.com)。一些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方法只会说它是一个类型为" function“的对象。我关注的是lambda的参数列表中的字符串和Foo类型。但据我所见,type_traits.h没有访问参数列表的任何东西。
GCC-11的一个特定选项是解压类型并解析结果字符串。但是,是否有一个不同的模板特性可以让我在编译时获得lambda的参数列表?
发布于 2015-06-17 02:38:25
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的必须声明与它们相关的签名。
MessageName< void(std::string const&, Foo const&) > UPDATE{"update"};就像上面提到的。
然后,当您添加一个处理程序时,对add_handler的调用将根据所需的签名检查分配的函数,并给出一个std::function。
类似地,当您发送消息时,可以根据签名检查传递的类型。您甚至应该将参数转换为函数正文中的每个签名参数类型。
这将尽可能多地将类型检查移到编译时,这是很好的C++风格。
发布于 2015-06-16 14:47:43
不这是不可能的。如果对象不是lambda,而是带有重载的结构呢?或者是一只聚兰花?您不能假设函数对象有一个而且只有一个签名-有很多方法可以获得多个签名。
下面是一个简单的例子:
struct fun {
int i;
void operator()(int x) {}
void operator()(float x) {}
};关于这个结构或它的任何一个论点,没有什么不复杂的或非POD的。
https://stackoverflow.com/questions/30870935
复制相似问题