2014-10-10 90 views
1

我想這取決於類型調用不同的功能於一身的模板功能不同的功能,例如:呼籲取決於類型

template<typename T> 
T func() { 
    static_assert(std::is_same<T, int>::value || /* other allowed types */ , "Type not allowed"); 

    T ret {}; 
    // if T == int 
    funcInt(&ret); 
    // if T == /* other types */ 
    /* other functions */ 

} 

這種事可能嗎?

我嘗試這樣做:

std::function< int(*T)> query; 
if (std::is_same<T, int>::value) { 
    query = funcInt; 
} 

,但是這給了我一個錯誤:

error: 'T' does not refer to a value

+1

我認爲這應該是'std :: function < int(T*)>查詢;',假設它是一個指向'T'參數的指針? – Niall 2014-10-10 07:58:27

+0

糟糕!恥辱對我來說,我認爲這是一些奇怪的模板錯誤... – gartenriese 2014-10-10 08:04:02

+0

如果我正確地讀了你,你仍然會有錯誤,因爲你的查詢不能存儲具有不能轉換爲T * – 2014-10-10 08:06:40

回答

5

is_same可以if語句中使用就好了:

if (std::is_same<T, int>::value>) { /* stuff */ } 
if (std::is_same<T, float>::value) { /* other stuff */ } 

Altough這個檢查是理論上在運行時完成,編譯器知道編譯時的所有值a nd很可能會刪除任何死支。缺點是func中的整個代碼需要在語法上和語義上形成良好,而不管T是什麼。這可能並不總是可行的。

正確的模板上下的方法是這樣的:

template<typename> 
struct helper; 

template<> 
struct helper<int> { static void do_work() { /* stuff */ } }; 

template<typename T> 
T func() 
{ 
    static_assert(std::is_same<T, int>::value || /* other allowed types */ , "Type not allowed"); 
    helper<T>::do_work(); 
} 

這允許你寫的東西,共同在func並把其餘的專業。

OTOH,如果func的簽名真的很簡單,並且不會有太多的代碼重複,那麼您也可以專注於func本身。

+0

「[...]」需要形成句法[...]「[...]」。這是否意味着我不能調用一個接受int的函數,因爲參數也可以是double,比如? – gartenriese 2014-10-10 08:29:28

+0

我想你可能能夠通過SFINAE刪除要求以形成良好的要求。 – sjdowling 2014-10-10 08:33:48

+1

@gartenriese你可以,因爲一個double可以轉換爲int,但它可能不是你想要發生的事情。例如,我可能會很奇怪地表達這種想法 - 不會有效的是[例如這樣的事情](http://coliru.stacked-crooked.com/a/6f3314362bbd748a)。這對你來說可能不是問題。 – jrok 2014-10-10 08:41:08