[英]Deduce non-type template parameter
是否可以從模板函數參數中推導出非類型模板參數?
考慮這個簡單的模板:
template <int N> constexpr int factorial()
{
return N * factorial<N - 1>();
}
template <> constexpr int factorial<0>()
{
return 1;
}
template <> constexpr int factorial<1>()
{
return 1;
}
我希望能夠改變factorial
以便我可以這樣稱呼它:
factorial(5);
並讓編譯器在編譯時計算出 N 的值。 這可能嗎? 也許有一些花哨的 C++11 補充?
我相信您當前的代碼通常會編寫如下:
constexpr factorial (int n)
{
return n > 0 ? n * factorial( n - 1 ) : 1;
}
如果你用一個常量表達式來調用它,比如factorial(5)
,那么所有的編譯器魔法都會發揮作用。 但是如果你做int a = 3; factorial(a)
int a = 3; factorial(a)
,那么我認為它會回到傳統的函數上——即它不會建立一個預先計算的答案的查找表。
通常,如果可以,您應該將每個函數和構造函數標記為constexpr
。 您不會丟失任何東西,編譯器會在必要時將其視為普通函數。
做不到,除非你有時光機。
函數的參數在運行時處理。 是的,在您的情況下,它是一個字面常量,但這是一個特例。
在函數定義中,參數類型在編譯時是固定的(因此可用於推導模板參數),但參數值僅在運行時固定。
你為什么需要這個? 只是這樣您就不必鍵入<>
嗎?
我認為你不能這樣做; 您可以這樣做的唯一方法是使用constexpr
函數參數,然后將其作為factorial
模板版本的template
參數傳遞,但不接受constexpr
函數參數。
不,你不能那樣做。 模板參數只能從函數參數的類型中推導出來,而不是value ,這通常在編譯時是不知道的。
當然,您可以將factorial
重寫為非模板constexpr
函數; 如果參數是已知的,那么它將在編譯時進行評估。
使用邪惡的宏:
#define factorial(X) factorial<X>()
解決此類問題的一種可能的解決方法是使用如下struct
:
template <int X>
struct constant {
operator int () { return X; }
};
然后我們可以像這樣對constant<X>
進行重載:
template <int X>
void f (constant<X>)
在編譯時和運行時使用X
值重載f (int)
。 煩人的部分是它需要在調用站點上進行一些紀律,因為每個文字常量都必須包裝為constant<X> {}
(使用宏或類似的東西)。
不,這是不可能的,除非你想創建一個巨大的 switch 語句:
int getFactorial( const int v )
{
switch ( v )
{
case 1 : return factorial<1>();
case 2 : return factorial<2>();
//etc
default:
;
}
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.