1

テンプレートを使用して、定数パラメーターのみが異なる関数のインスタンスをいくつか作成できますか? このパラメーターの選択肢の数は固定されています。例えば

書き直したくありません (上限は 1..32 の 2 乗)

funct(param, int upper)
 {
  some_loops(..)
     some_heavy_code_fast_for_const_and_slow_for_variable(upper)
 }

のセットに

funct_with_upper_is_1(param) // upper =1
 { manually_copied_code...heavy(1) }
funct_with_upper_is_2(param) // upper =2
 { manually_copied_code...heavy(2) }
funct_with_upper_is_4(param) // upper =4
 { manually_copied_code...heavy(4) }
funct_with_upper_is_8(param) // upper =8
 { manually_copied_code...heavy(8) }

しかし、テンプレート化された

template<int upper>
 funct_with_fixed_upper(param)
 { the_original_code....heavy(upper) }

その後

template<upper=1> funct_with_fixed_upper(param);
template<upper=2> funct_with_fixed_upper(param);
template<upper=4> funct_with_fixed_upper(param);
template<upper=8> funct_with_fixed_upper(param);

これは C++ テンプレートで可能ですか?

== 詳細モード ==

そのようなコードを含むC++ファイルがたくさんあります

function_typical(long long double ***A, long long double ***B, int const_1, int const_2)
// the type "long long double" here is very correct, this is extension of compiler
{

   for(int i=1;i<100000-1;i++)
      for(int j=1;j<100000-1;j++)
         for(int k=0;k<const_1;k++)
            for(int l=k;l<const_2;l++) {
                // some cray work with array like
                A[i][j][l-k]+=(B[i][j][l-k]+A[i+1][j][l-k]+A[i][j+1][l-k]-A[i-1][j][k]-A[i][j-1][l-k]/2.2)/88.3;
                if(A[i][j][l-k]>sin_lld(A[i][j-1][l-k])){B[i][j][l-k]=A[i][j][k]*4;}
            }
 }

これは単なる例ですが、次のとおりです。

  • ループを交換できません。
  • 2 つの外側のループ、i & j には多くの反復があります
  • 2 つの内部 (ネストされた)、k& l には少しの繰り返しがあり、その回数はに渡され、function_typicalそれらのセットは固定されています。たとえば、const_1 と const_2 は (2,3)、(4,5) のペアの 1 つです。 、(3,5)。許容されるペアの合計数が 10 未満です。

このコードの問題は、速度が非常に遅いことです。このコードの const_1 と const_2 を数値定数に修正すると、コンパイラは最適化で素晴らしい仕事をします (たとえば、すべての k とすべての l の反復を展開し、いくつかのスマートな仕事を行います)。

しかし、(const_1 と const_2) ペアのすべてのセットのすべての典型的な関数を物理的に変更することはできません。また、コンパイラの定数プロパゲータは、セット情報の定数を関数に伝搬できません (これはネットワーク サーバーであり、クライアントは固定セットから const_1 と const_2 のペアを選択します)。

だから私はコンパイル時にペアのすべての選択肢を知っています。しかし、すべての関数を手作業で書き直す機会はありません。

== 詳細モード オフ ==

前もって感謝します

4

2 に答える 2

5

絶対に、これは完全に可能です。テンプレートで int を取得すると、定数式が有効な場所であればどこでも有効です。

template<int const_1, int const_2> function_typical(long long double ***A, long long double ***B)
// the type "long long double" here is very correct, this is extension of compiler
{

   for(int i=1;i<100000-1;i++)
      for(int j=1;j<100000-1;j++)
         for(int k=0;k<const_1;k++)
            for(int l=k;l<const_2;l++) {
                // some cray work with array like
                A[i][j][l-k]+=(B[i][j][l-k]+A[i+1][j][l-k]+A[i][j+1][l-k]-A[i-1][j][k]-A[i][j-1][l-k]/2.2)/88.3;
                if(A[i][j][l-k]>sin_lld(A[i][j][l-k])){B[i][j][l-k]=A[i][j][k]*4;}
            }
 }

これはそのまま再コンパイルする必要がありますが、呼び出しサイトを変更する必要があります。また、テンプレート化されたコードはすべての翻訳単位に完全なソースが必要であり、1 つの翻訳単位だけで定義することはできないことを忘れないでください。

于 2010-10-27T22:00:22.737 に答える
1

元のテンプレートを提供:

template<int upper> 
  funct_with_fixed_upper(param)
  { the_original_code....heavy(upper) }

それを呼び出すときは、次のようにします。

 funct_with_fixed_upper<1>(param);
 funct_with_fixed_upper<2>(param);`

定数に基づいてそれらのいずれかを特殊化する必要がある場合は、次のようにします。

 template<> funct_with_fixed_upper<1>(param) { // code here };

他の人がすでに言ったように、これはコードのメンテナンスを簡素化しますが、コンパイラがこれを拡張するため、コンパイルされたコードのサイズを実際には縮小しません...

于 2010-10-27T22:15:37.720 に答える