运行时的模板实例化和函数选择

时间:2014-10-29 10:12:47

标签: c++ templates runtime

我对c ++很陌生,我正试图做一些有点棘手的事情,我似乎无法找到一个令人满意的解决方案。

假设我有这两个功能:

template <class T1, class T2> void foo(T1 param1, T2 param2){...}; 
template <class T1, class T2> void bar(T1 param1, T2 param2){...};

在运行时,我想选择这两个函数,并使用从用户输入获得的一些模板类型来实例化它,比如char c。所以我可以这样做:

double d;
float f;
switch(c) {
    case 'a':
        foo(d, f); break;
    case 'b':
        foo(f, d); break;
    case 'c':
        bar(d, f); break;
    case 'd':
        bar(f, d); break;

但是这个解决方案很丑,不可扩展(我希望能够添加更多功能,以及更多模板参数)等等。另外,我看不到分配其中一个函数的方法{{1} }或foo到函数指针,因为模板参数在运行时之前是未知的。

因此,如果有人可以为我提供一个很好,干净的解决方案,我会非常高兴!欢呼声。

修改让我澄清一些事情。

我正在访问二进制文件,其中数据可以存储为barfloats。显然,程序无法知道这种类型,因此用户必须以某种方式指定它。

然后必须对从文件加载的数据进行一些数学计算。并且有几种计算可能,上面用函数doublesfoo表示。

所以我希望用户能够在运行时中指定文件中的数据类型,然后在运行时选择要应用于加载数据的函数< / em>的。 bar只是说明了我认为用户可以选择这样的内容。

1 个答案:

答案 0 :(得分:1)

你不能指向函数模板,因为它们不是函数,但需要先实例化。你可以得到这样的指针:

typedef void (*Tfkt_int_int)( int, int );
Tfkt_int_int Ptr = &foo<int,int>;

如您所见,您需要指定可能的类型组合。

如果有很多,并且您想要更清晰的代码,则可以将共享相同签名的所有函数放入一个映射中。 (也就是说,每个签名需要一个映射。)然后区分在switch语句中使用哪个映射。

std::map<char, Tfkt_int_int> Map_int_int;
Map_int_int['a'] = &foo<int,int>;
Map_int_int['b'] = &bar<int,int>;
// more ...

typdef void (*Tfkt_int_double)( int, double );
std::map<char, Tfkt_int_double> Map_int_double;
Map_int_double['a'] = &foo<int,double>;
Map_int_double['b'] = &bar<int,double>;
// more ...

如果你只想要一张地图,并愿意牺牲一些类型的存款,你可以围绕参数类型进行转换。因为你已经从字节流中读取了数据,所以在你的情况下可能没那么多损失。

template <class T1, class T2> void foo(char* param1, char* param2)
{
  T1 P1 = *(reinterpret_cast<T1*>( param1 ));
  T2 P2 = *(reinterpret_cast<T2*>( param2 ));
  // ...
};

typedef void (*Tfkt)( char*, char* );
std::map<char, Tfkt> Map;
Map['a'] = &foo<int,int>;
Map['b'] = &foo<int,double>;
// more ...

然后打电话给:

double d;
int i;
char c = 'b';
(*(Map[c]))( reinterpret_cast<char*>(&i), reinterpret_cast<char*>(&d) );