【发布时间】:2015-09-01 11:16:16
【问题描述】:
我正在使用可变参数模板来捕获 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 方法只会说它是“函数”类型的对象。我从 lambda 的参数列表中寻找字符串和 Foo 类型。但据我所知,type_traits.h 缺少访问参数列表的任何内容。
GCC-11 特定的选项是解开 typeid 并解析结果字符串。但是是否有一个可变参数模板功能可以让我在编译时访问 lambda 的参数列表?
【问题讨论】:
-
所以,行话。 “upcall”只是带有额外行话的“callback”?
g.Handlers[UPDATE]的类型是什么?Group是你的类型,还是 Isis?什么是“真正的 OrderedSend”?您的示例代码中有一个 OrderedSend,它是真的还是假的?在上面的代码中,您在哪里“扫描 lambda”?我的意思是,你有你 调用 lambda 的类型,你为什么认为你需要 lambda 的签名?为什么你认为 lambda 的(?an?)参数列表会有所帮助? -
哦,你是Isis2的作者。所以我猜“你的代码”和“isis2 代码”之间的区别有点武断。但我浏览了 Isis2 的
.h文件,它没有包含Group类型,也没有OrderedSend方法。 C# 代码库中似乎确实有一些,您是否正在尝试编写当前 C# 库的 C++ 版本,并且您上面的代码是您想要在 C++ 中工作的示例?这确实解释了new Foo绑定到Foo&的奇怪之处(指针和引用是不同的类型,string&不会绑定到"hello")。UPDATE包含哪些信息? -
那么,通过
UPDATE发送的所有消息都必须具有相同的签名,对吧?并且所有听众都必须与该签名兼容?为什么要在使用点(消息生产和消费)推断签名,然后在它们不匹配时导致运行时错误,而不是在一个位置定义消息语法(例如,定义UPDATE的位置) ,如果发送者发送不兼容的类型,或者如果侦听器注册了不兼容的回调,则在使用点生成编译时错误? -
@Yakk:只是一个回调。 G.Handlers 是 std::vector
的数组。我将它们声明为 (void*)() 因为我不知道人们将实际注册的类型。至于 OrderedSend,真正的方法需要一个参数向量及其类型。我使用可变参数 temp,ate 来生成它(在 C# 中,这就是你使用 varargs 得到的) -
@Yakk:你是如何“查看 Isis2 的 .h 文件”的?我还没有发布它。有一个 C# 库,这是你的意思吗?是的,我将它翻译成 C++,目的是将它放到启用 RDMA 的 NIC 上。该卡无法运行 Mono,所以我需要从 C# 转移到 C++。无论如何,RDMA 想以光线速度进行内存-内存 DMA,而托管内存我显然做不到,这也主张在这个新版本中使用 C++...
标签: c++11 lambda variadic-templates isis2