簡體   English   中英

推導非類型模板參數

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM