Question

Utiliser modèle Puis-je créer plusieurs instanciations d'une fonction, différentes que dans un paramètre constant? Le nombre d'alternatives pour ce paramètre est fixe. Par exemple.

Je veux pas réécrire (où est supérieure à 1..32 dans des puissances de deux)

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

en un ensemble de

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) }

mais dans templated

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

et

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);

Est-ce possible avec les tempaltes C +?

== Mode verbeux sur ==

J'ai des fichiers beaucoup C ++ avec le code comme ça

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;}
            }
 }

Ceci est juste un exemple, mais:

  • Je ne peux pas échanger les boucles;
  • les 2 boucles externes, i et j ai beaucoup d'itérations
  • le 2 interne (imbriqué), k et l ont un peu d'itérations, nombre qui est passé dans le function_typical et l'ensemble d'entre eux sont fixés, par exemple, const_1 et const_2 est l'une des paires: (2,3), (4,5), (3,5). Nombre total de paires autorisées est plus petite que 10.

Le problème avec ce code est sa vitesse est très faible. Si je fixerai const_1 et const_2 dans ce code à des constantes Numberic, compilateur fera un excellent travail dans l'optimisation (déroulage tout k par exemple et toutes les itérations de l, en faisant un peu d'emploi à puce).

Mais je ne peux pas changer physiquement chaque type comme fonction de chaque ensemble de (const_1 et const_2) paire. En outre, propagateur constante de compilateur constantes ne peuvent pas Propager de l'info ensemble de la fonction (ce qui est un serveur de réseau et le client fait une sélection des const_1 et const_2 paire forment ensemble fixe).

Je sais que dans la compilation de toutes les alternatives de paires. Mais je n'ai aucune chance de réécrire toutes les fonctions à la main.

== verbose mode off ==

Merci à l'avance

Était-ce utile?

La solution

Absolument, cela est tout à fait possible. Si vous prenez un int par modèle, il est valable chaque fois une expression constante est valide.

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;}
            }
 }

Cela devrait recompiler droite, mais vous devrez modifier les sites d'appel. En outre, ne pas oublier que le code doit avoir templated la source complète dans toutes les unités de traduction et ne peut pas être défini en un.

Autres conseils

fourni votre modèle d'origine:

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

Quand vous appelez, vous le feriez comme ceci:

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

si vous avez besoin de se spécialiser l'un d'eux en fonction de la constante que vous feriez comme ceci:

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

et comme d'autres l'ont déjà dit, cela simplifiy votre maintence de code, mais ne réduirait pas vraiment la taille du code compilé comme le compilateur élargirait encore ceci ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top