foreach是在编译时执行的吗?

时间:2012-09-20 15:31:52

标签: d

我编写了这段代码来获取指针传递的函数类型:

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内推导出它们?

2 个答案:

答案 0 :(得分:3)

foreach将在编译时展开,但代码执行(如运行时只有函数如write)可以推迟到运行时

这与循环展开相当,但这里没有计数器但每次迭代都有唯一类型

答案 1 :(得分:1)

    您在示例中的
  1. get_param_types()在运行时进行评估,因为您在运行时在main()中调用它。请注意,它不能在编译时按原样进行计算,因为您正在调用write()和writeln(),这些函数写入stdout,这在编译时是不可用的。
  2. 你想在编译时实现什么?对writewriteln的所有调用只能在您的示例中在运行时进行。 foreachstatic if在编译时进行评估...实际上,对该函数的任何调用都将在运行时调用writewriteln的组合 - 无循环或者条件 - 这就是你想要的吗?
  3. 您可能希望了解template alias parameters。他们看起来有点像这样:
  4. void getParamTypes(alias fn)() if (isCallable!fn)
    {
        writefln("Getting parameter types for fn: %s", (&fn).stringof[2..$]);
        foreach (param; ParameterTypeTuple!fn) {
            writeln(param.stringof);
        }
    }