2010-03-16 76 views
2

是否可以真正使用作爲控制流模板傳遞的類型?我想編寫使用模板的功能,進而調用基於傳遞類型另一個功能:使用在C++中作爲模板傳遞的類型

template <class T> void test_function (T var) 
{ 
    //Do stuff 
    if (T == char) { 
     bar (var); 
    } else { 
     foo (var); 
    } 
    //Do even more stuff 
} 

如果不是這樣,我將不得不退回到枚舉...

編輯: 到目前爲止的所有答案都建議我使用模板專業化。我並不是非常具體,但這與不使用模板完全相同,因爲對於每種不同的類型,都有一個不同的函數調用。

+0

給出一個例子,說明你實際在做什麼,這樣我們可以回答真正的問題。 – GManNickG 2010-03-16 23:23:32

回答

6

您通常使用專門爲:

template<class T> void forward(T t) { 
    // ... 
} 

template<> void forward<char>(char c) { 
    // ... 
} 

template<class T> void test(T t) { 
    forward<T>(t); 
} 

這讓你有效地「編譯時分支」

+0

''錯誤放置了(它實際上是用另一個模板有一個類型爲'char' :)的未命名的非類型模板參數)。修正了,希望你不要介意:) – 2010-03-16 21:59:29

+0

確實,謝謝:) – 2010-03-16 21:59:55

+0

另一種方法是在你不想爲大多數類型做什麼的時候:'void forward(...){}'會匹配所有類型,並且什麼都不做,並且那麼你只需要'forward(char)'等的重載就可以實際操作的類型。 – 2010-03-16 23:08:22

1

您可以使用模板專門化。 這意味着你可以定義爲通用 無效test_function(T)和比空隙test_function(char)的不同實現

+0

是的,這是可能性之一,但我更喜歡使用模板,因爲它只是一個區分不同版本的單個函數調用,並且我將爲該函數使用的每種類型都有一個不同的函數調用。 – moatPylon 2010-03-16 21:48:03

+0

@MeDiCS:但在C++中,編譯時間if是通過專業化完成的。要麼專門針對每種類型,要麼你超載。沒有其他辦法可以做到這一點。 – sbi 2010-03-16 21:58:28

+0

@sbi:明白了,謝謝。現在我可以更多地理解爲什麼有些人似乎討厭C++¬¬。 – moatPylon 2010-03-16 21:59:47

4

這是可能要做到這一點,但它是幾乎從來沒有一個好主意,這樣做。一個更好的想法就是分解出常見的位併爲這些特定類型的功能提供過載,例如,

template <class T> void test_function_prologue (T var) 
{ 
    //Do stuff 
} 

template <class T> void test_function_epilogue (T var) 
{ 
    //Do even more stuff 
} 

template <class T> void test_function (T var) 
{ 
    test_function_prologue(var); 
    foo (var); 
    test_function_epilogue(var); 
} 

void test_function (char var) 
{ 
    test_function_prologue(var); 
    bar (var); 
    test_function_epilogue(var); 
} 
+0

+1:我發現這種非模板重載的形式更清晰。 – quamrana 2010-03-16 22:06:05

+0

當涉及到免費函數時,這裏有一個關於重載而不是專門化的詳細論點:http://www.gotw.ca/publications/mill17.htm – 2010-03-17 00:19:46

2

只要foo()接受類型爲char的參數,並且bar()接受任何T,這將是可能的。否則不是。即使一個分支從未被採用,兩個分支都必須是可以編譯的,以便你實例化模板。如果兩個分支對於任何T都不可編譯,則沒有選擇使用編譯時分支(在任何情況下都是可取的)。

否則,你可能會使用運行時類型識別:

if (typeid(T) == typeid(char)) 

或編譯時檢查:

if (boost::is_same<T, char>::value) 

其中is_same可以實現爲

template <class T, class U> 
struct is_same { static const bool value = false; }; 

template <class T> 
struct is_same<T, T> { static const bool value = true; }; 
1

即使你的編輯迴應,我仍然會建議模板專業化。你只是做一個代理函數,調用你想要的函數:

template <class T> void call_other_function(T var) 
{ 
    foo(var); 
} 

template <> void call_other_function<char>(char var) 
{ 
    bar(var); 
} 

template <class T> void test_function (T var) 
{ 
    //Do stuff 
    call_other_function(var); 
    //Do even more stuff 
} 
相關問題