我希望设计一个类型安全的 NxM cross-connect。这是一种允许 N 个函数输出中的任何一个连接到 M 个输入中的任何一个的机制。或者换句话说,将一个函数(来自一组函数)的返回值与另一个函数的参数连接起来。一个关键方面是这些连接必须在运行时可配置。我遇到的主要问题是输入的类型与输出的类型不同,具体取决于每个连接。
假设在程序中的某个任意点,我想将 的返回值连接float foo()
到val
.void bar(double val)
我目前有两个代表输入和输出的参数化类,分别命名为Source<T>
和Dest<U>
. T & U 应该是 float、double、bool、int、unsigned int 等。我有一个异构的Source<T>
实例集合,一些 double、一些 float、一些 int、一些 bool。还有一个异构的Dest<U>
实例集合,也有一些 double、一些 float、一些 int、一些 bool。有时 T 和 U 是同一类型。对于更多上下文,这些实例都与唯一名称相关联,允许更高级别的系统说“现在请连接 source::foo 与 dest::bar”,或“删除 source::red 和 dest::blue 之间的关联”。
在前面的示例中,在编译时,foo()
程序员知道 from 的返回值类型是 float 并且可以在源代码中指定,因此Source<float>
可以实例化 a 并与此函数关联。并且参数 to 的类型bar()
也是已知的,因此Dest<double>
可以实例化 a 并将其与此函数关联(使用std::function
包装器)。然后在运行时 Source<float>
可以与 相关联并通过多态指针(通过所有实例共享的继承接口)Dest<double>
将值传递给。然后将使用包装器调用该函数。Dest<double>
Dest<U>
Dest<double>
bar()
std::function
因此,在运行时,目标是将 anySource
与 any关联Dest
任意时间,并随时重新关联。所以我需要一种方法来创建一个函数,该函数可以将T
只在运行时知道的类型转换为另一种U
也只在运行时知道的类型。
稍微复杂一点的是,返回值和参数值实际上可能是任意大小的数组。例如,foo()
可能返回一个float[32]
数组,但bar()
可能期望一个double[8]
数组(可能会丢弃每 4 个值中的 3 个)。我的想法是,一旦它可以处理类型转换,这个“桥”机制就会处理这个问题。
坦率地说,我并没有真正看到如何实现这一点。如果 Source-to-Dest 关联在编译时已修复,我可以编写一系列模板Bridge<T,U>
函数来进行转换,但因为这一切都需要在运行时发生,我认为这不是答案。
Bridge<T,U>
编写通用函数,然后创建某种动态调度机制以在运行时根据 T 和 U 选择合适的调度机制是最好的方法吗?为了选择正确的实例,我将如何在运行时确定 T 和 U 的类型Bridge
?我还想抓住 T 和 U 是同一类型的情况,因此避免任何不必要的转换(作为优化)。
还是有更好的方法来完成我想做的事情?