对于Unity(C#)和C ++插件之间的接口,我需要用在Unity中定义的两个模板参数实例化一个类。我无法直接传递C ++类型,因此我改用char
和switch
语句。
对于单个参数,它看起来像这样:
char type = 'I'; // For example; in practice, it is set from a Unity plugin call)
switch (type)
{
case 'I':
{
ExtArrayExporter<int> * data_link = new ExtArrayExporter<int>(static_cast<int*>(external_array), ext_array_length);
return(EXT_TYPES::RegisterNew(data_link));
}
case 'F':
{
ExtArrayExporter<float> * data_link = new ExtArrayExporter<float>(static_cast<float*>(external_array), ext_array_length);
return(EXT_TYPES::RegisterNew(data_link));
}
case 'B':
{
ExtArrayExporter<bool> * data_link = new ExtArrayExporter<bool>(static_cast<bool*>(external_array), ext_array_length);
return(EXT_TYPES::RegisterNew(data_link));
}
}
问题:
[ExtArrayExporter
需要两种类型并且我有两个来自Unity的字符时,如何实现?
通常会堆积switch
语句,但是这种语句会迅速增长,需要考虑更多类型,并且是重复的。
我希望可以为变量分配类型,例如,使该方法从上面保留,但是显然不能编译:
auto type_a = int;
C ++是否可以为这种情况提供任何平滑的解决方案?
我不知道ExtArrayExporter
,EXT_TYPES
等,因此我提出了一个通用代码,您可以根据需要进行调整。
它基于递归可变参数模板foo()
函数,如下所示
// ground case
template <typename ... Ts>
void foo ()
{ /* do something with Ts... */ }
// recursive case
template <typename ... Ts, typename ... Cs>
auto foo (char c0, Cs ... cs)
{
switch ( c0 )
{
case 'I':
return foo<Ts..., int>(cs...);
break;
case 'F':
return foo<Ts..., float>(cs...);
break;
case 'B':
return foo<Ts..., bool>(cs...);
break;
// ...
}
}
您可以如下使用它
foo<>('I', 'B', 'F', 'B', 'B', 'I');
或也简单地
foo('I', 'B', 'F', 'B', 'B', 'I');
想法是,每次调用foo()
都会消耗一个char
参数,将其转换为模板参数,然后将其添加到Ts...
可变参数列表中;当char参数结束(基本情况)时,可以使用解析的Ts...
模板参数。
请注意,此解决方案是通用的,不仅适用于2个,而且适用于不确定数量的参数。