3

次のようなテンプレートをインスタンス化すると、次のようになります。

template<int i>
int ReturnMeDouble()
{
    return 2 * i;
}

次に、コンパイラはコンパイル時に i の値を評価できる必要があります。私の問題は、変数に応じてプログラムで2つの関数のいずれかを呼び出す必要があることです(簡単にするために馬鹿げています)。私のコードは次のようになります。

int returnValue = 0;
switch(value)
{
    case 1:
    case 2:
    case 3:
    case 4:
        returnValue = ReturnMeDouble<value>();
        break;
    case 5:
    case 6:
        returnValue = ReturnMeTriple<value>();
        break;
}

本当の ReturnMe... 関数は、それほど単純ではありません。明らかに、この switch ステートメントを使用して、各 case ステートメントの下に個別の呼び出しを提供できますが、最初のケースで、ReturnMeDouble は、4 つの値のいずれかでのみ呼び出すことができます。

コンパイラは、インスタンス化が必要な 4 つの個別の関数テンプレートの周りに条件付きフローを配置する必要があり (事実上、手動で行うことを避けようとしていること)、その方法がわからないというだけですか?

これを行うよりエレガントな方法はありますか?

編集:明確にするために-それほど重要ではない実装では、整数値を使用して、関数内の型選択にいくつかのメタプログラムを適用します。

4

2 に答える 2

2

私はあなたが試みた説明でそれをかなり釘付けにしたと思います。

物事を見る標準的な方法は、テンプレート引数として指定する値は、コンパイル時に既知の定数でなければならないということです。指定した値は実行時までわからない変数であるため、単に許可されていません。

はい、この特定のケースでは、まともなオプティマイザーを備えたコンパイラーは、おそらく、指定した4つのケースに提供する必要がある4つの定数値を把握できます。

ただし、それほど明確ではない可能性が高いケースがかなり多くあります。たとえば、特定の最適化を組み込んだコンパイラは、特定の値が実際にはコンパイル時の定数であることを理解できますが、その特定の最適化を欠いている別のコンパイラはそれを認識できません。

彼らが答えられなかった質問 (「コンパイラはコンパイル時にこの値を推測できるか?」) に直面した委員会は、かなり保守的なアプローチを取り、許容される入力の比較的狭い範囲を指定しました。もちろん、コンパイラは他の式を拡張機能として受け入れることもできます。

constexpr委員会の観点からは、追加は、少なくともかなり類似したもののかなり一般的な実装を試みる試みであったと思います。結果がコンパイルとして利用可能であるべきであることをコンパイラーに知らせる方法で、はるかに広い範囲の計算を実行できるようにします。 -時定数。それさえも実装する複雑さを考えると、上記のような場合にコンパイル時の計算を義務付けることは(少なくとも近い将来には)ありそうにないと思います。

于 2013-05-15T14:28:50.463 に答える
1

関数のテンプレート パラメーターが使用される「ささいな」方法を教えてくれないので、これを解決する方法は、関数のテンプレートを解除し、ランタイムを渡すことだと言います。パラメータ。

次に、実行時からコンパイル時の値への変換をどこでも行う必要はありません。値は、すべての場合に実行時に渡されるだけです。

言い換えると:int ReturnMeDouble(int i) { ... }

于 2013-05-15T14:26:51.707 に答える