2014-10-29 73 views
3

我對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; 

但是這種解決方案是醜陋的,不可擴展的(我希望能夠增加更多的功能,更多的模板參數)等。還有,我看不到方式將foobar的功能之一分配給函數指針,因爲模板參數在運行時前是未知的。

所以如果有人能夠爲我提供一個很好的,乾淨的解決方案來解決這個問題,我會非常高興!乾杯。

編輯讓我澄清一些事情。

我正在訪問二進制文件,其中的數據可以存儲爲floatsdoubles。顯然,程序無法知道這種類型,所以用戶必須以某種方式指定它。

然後必須對從文件加載的數據進行一些數學計算。並且有幾種可能的計算,上面由foobar功能表示。

所以我希望用戶能夠在運行時指定數據類型的文件中,然後選擇功能在運行時也應用於加載的數據switch(c)只是我認爲用戶可以選擇這些東西的一個例證。

+0

你可以給它是什麼你想達到某種背景? – 2014-10-29 10:16:30

+0

調用應遵循的模式究竟是什麼(相對於'c')? – Columbo 2014-10-29 10:18:50

+0

模板在運行時不起作用。你可以創建一個'unordered_map '並根據該鍵調用它。 – 2014-10-29 10:20:31

回答

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)); 
+0

您的回答確實幫助我解決了我的問題,儘管我沒有完全按照這種方式實施。謝謝! – dranitou 2014-11-03 15:30:29