2017-05-05 87 views
1

我最近一直在用C++學習模板元編程。 在檢查計算階乘例子後,想知道是否只能用模板函數而不是模板類來完成同樣的事情。 我第一次嘗試如下所示使用模板函數的C++模板元編程

#include <stdio.h> 
#include <iostream> 

using namespace std; 

template <int t> 
int multiply(t) 
{ 
    return (multiply(t-1) * t); 
} 

template <> 
int multiply(1) 
{ 
    return 1; 
} 

int main() { 
    cout << multiply(5) << endl; 
    return 0; 

} 

但我

temp.cpp:7: error: template declaration of 'int multiply' 
temp.cpp:14: error: expected ';' before '{' token 
temp.cpp: In function 'int main()': 
temp.cpp:19: error: 'multiply' was not declared in this scope 

能做些什麼用模板函數以下編譯器錯誤,例如模板元編程得到什麼?這是否允許?

+3

函數聲明需要聲明參數類型而不是參數值。 'int multiply(t)'沒有任何意義,無論是否爲模板 – user463035818

+0

請注意,您鏈接的示例中的遞歸是關於類型(即發生在編譯時),而您在此嘗試執行的遞歸是關於調用函數(即它發生在運行時)。也許有一種方法可以使用模板函數,但是當您使用遞歸運行時調用來計算因子時,您不需要模板 – user463035818

+0

有沒有一種方法可以在編譯時使用模板函數來完成此操作,就像我鏈接的示例中一樣? – vibz

回答

2

如評論中tobi303所述,僅使用(t)作爲函數的參數列表,其中t不是類型名稱,這是沒有意義的。

由於int t是模板參數,不是正規的參數,它應該只存在於模板參數列表(<>尖括號之間),而不是在功能參數列表(()括號之間)。模板參數也必須如此傳遞,即代碼中的multiply<5>()而不是multiply(5)

您可以使用類似:

#include <iostream> 

using namespace std; 

template <int t> 
constexpr int multiply() { 
    return multiply<t - 1>() * t; 
} 

template <> 
constexpr int multiply<1>() { 
    return 1; 
} 

int main() { 
    cout << multiply<5>() << endl; 
    return 0; 
} 

還請注意,我添加constexpr(C++ 11或更高版本),以便隨時能在編譯時間來評估這些功能。但是,編譯器不會被迫在編譯時而不是運行時對它們進行評估,並且最終還是會導致運行時開銷。

+2

'constexpr'不會在編譯時強制執行評估。 –

+2

強制編譯時間評估:'constexpr auto fact5 = multiply <5>(); std :: cout << fact5 << std :: endl;' – Jarod42

+0

@ Jarod42什麼保證? – jotik