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) , (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;}
            }
 }

这应该直接重新编译,但是您必须更改调用站点。此外,不要忘记模板化代码必须在所有翻译单元中都有完整的源代码,并且不能只在一个单元中定义。

于 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 回答