2012-09-20 2 views
0

J'ai écrit ce morceau de code pour mettre la main sur les types d'une fonction transmise par un pointeur:Foreach est-il exécuté au moment de la compilation?

import std.stdio; 
import std.traits; 

void main() 
{ 
    get_param_types(&f1,"f1"); 
    get_param_types(&f2,"f2"); 
    get_param_types(&f3,"f3"); 
} 

void get_param_types(f_t)(f_t f, string f_id){ 
    writeln("get_param_types "); 
    alias ParameterTypeTuple!(f) ptt; 
    writeln(f_id, " has ", ptt.length, " parameters"); 
    static if (ptt.length){ 
    write("("); 
    foreach (pt; ptt){ 
     write(typeid(pt), " "); 
    } 
    writeln(")"); 
    } 
} 

void f1() { } 
void f2(int x) { } 
void f3(int x, double y, string z) { } 

Mon doute est: 1: Est-ce get_param_types complètement évalué au moment de la compilation?

Si non: 2: Comment puis-je y parvenir?

Et pendant que j'y suis ... 3: Est-il possible d'éviter de passer les chaînes (par exemple "f1") et les déduire de l'intérieur get_param_types au moment de la compilation?

Répondre

1
  1. get_param_types() dans votre exemple est évaluée lors de l'exécution, que vous appelez lors de l'exécution dans main(). Notez qu'il ne peut pas être évalué au moment de la compilation tel quel, car vous faites des appels à write() et writeln() qui écrivent à stdout, qui n'est pas disponible au moment de la compilation.
  2. Qu'est-ce que vous voulez atteindre au moment de la compilation? Tous les appels à write et writeln peuvent uniquement se produire lors de l'exécution dans votre exemple. Les foreach et static if sont évalués au moment de la compilation ... Essentiellement, tout appel à cette fonction appellera simplement une combinaison de write et writeln - pas de boucles ou conditionnelles - est ce que vous voulez? Vous voudrez peut-être regarder dans template alias parameters. Ils regardent un peu comme ceci:
void getParamTypes(alias fn)() if (isCallable!fn) 
{ 
    writefln("Getting parameter types for fn: %s", (&fn).stringof[2..$]); 
    foreach (param; ParameterTypeTuple!fn) { 
     writeln(param.stringof); 
    } 
} 
+0

Les appels 'write' sont juste pour le débogage. Donc, si je me débarrasse d'eux (ou "débogage", je vais modifier le poste), il sera exécuté au moment de la compilation, non? J'étais sûr de 'static if' que de' foreach'. Le combi 'alias'-'stringof' fonctionne comme le charme! A quoi sert le 'isCallable'? Pour autant que je puisse le voir, il suffit de raccourcir le message d'erreur quand j'appelle la fonction avec un appel non ... – steffen

+0

foreach() sera déroulé au moment de la compilation lors de l'itération sur un tuple. Autrement dit, il n'y aura pas d'itération à l'exécution, ce sera juste une liste d'instructions. IsCallable spécifie que l'alias doit être quelque chose qui peut être appelé (une fonction, delegate, struct ou class avec opCall()). Cela tend à clarifier les messages d'utilisation et d'erreur. – Robert

3

foreach sera élargi au moment de la compilation, mais l'exécution de code (comme le moteur d'exécution ne fonctionne comme écriture) peuvent être différés à l'exécution

c'est comparable au déroulement de la boucle mais pas avec un compteur mais un type unique à chaque itération

Questions connexes