0

ポインターによって渡される関数の型を取得するために、次のコードを作成しました。

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

私の疑問は次のとおりです。1:get_param_typesコンパイル時に完全に評価されますか?

そうでない場合: 2: どうすればこれを達成できますか?

3: 文字列 (例: ) を渡さないようにして、コンパイル時内部から推測する方法はありますか?"f1"get_param_types

4

2 に答える 2

3

foreach はコンパイル時に展開されますが、コードの実行 (書き込みなどのランタイムのみの関数など) はランタイムまで延期できます。

これはループの展開に匹敵しますが、ここではカウンターではなく、反復ごとに一意の型を使用します

于 2012-09-20T18:52:24.273 に答える
1
  1. get_param_types()で実行時に呼び出しているため、例では実行時に評価されますmain()。コンパイル時に利用できない に書き込む write() および writeln() を呼び出しているため、コンパイル時にそのまま評価することはできないことに注意してくださいstdout
  2. コンパイル時に何を達成したいですか?writeandへのすべての呼び出しはwriteln、例の実行時にのみ発生します。foreachandはstatic ifコンパイル時に評価されます...基本的に、その関数への呼び出しは、実行時にwriteandの組み合わせを呼び出すだけwritelnです-ループや条件なし-これはあなたが望むものですか?
  3. テンプレート エイリアス パラメータを調べることをお勧めします。それらは次のように見えます。
void getParamTypes(alias fn)() if (isCallable!fn)
{
    writefln("Getting parameter types for fn: %s", (&fn).stringof[2..$]);
    foreach (param; ParameterTypeTuple!fn) {
        writeln(param.stringof);
    }
}
于 2012-09-20T16:31:55.930 に答える