質問

テンプレート関数パラメーターから非タイプのテンプレートパラメーターを推定することは可能ですか?

このシンプルなテンプレートを考えてみましょう。

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), 、それから私はそれが従来の機能に戻るだろうと思います - つまり、それは事前に計算された答えのルックアップテーブルを構築していません。

一般に、すべての関数とコンストラクターを次のようにマークする必要があります constexpr できれば。あなたは何も失いません、コンパイラは必要に応じて通常の関数としてそれを扱います。

私はあなたがそれをすることができるとは思わない。あなたができる唯一の方法は constexpr 次に渡される関数パラメーター template のテンプレートバージョンのパラメーター factorial, 、 しかし constexpr 関数パラメーターは認められません。

いいえ、巨大なスイッチステートメントを作成したくない限り、それは不可能です。

int getFactorial( const int v )
{
  switch ( v )
  {
    case 1 : return factorial<1>();
    case 2 : return factorial<2>();
    //etc
    default:
       ;
  }
  return 0;
}

いいえ、それはできません。テンプレート引数は、からのみ推測できます タイプ 関数引数の、ではありません 価値, 、一般的にコンパイル時には知られていません。

もちろん、書き直すことができます factorial テンプレート以外として constexpr 関数;その後、引数が知られている場合、コンパイル時に評価されます。

邪悪なマクロを使用してください:

#define factorial(X) factorial<X>()
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top