2

在 D 中,模板实例化是在 mixin 出现的范围内评估的,而不是在定义模板声明的地方。当在 mixin 出现的范围内评估 body 时,可以使用模板 mixins。但是,当我有一个模板函数并且我希望它的主体在调用范围内进行评估时,我该怎么办?我找不到将其翻译成等效的方法。

让我们以以下示例为例,其中包含两个模块,module1并且module2

module module1;
import std.stdio;
public void test(string field)(string msg)
{
    mixin("static if (__traits(isArithmetic, " ~ field ~ " )) \n"
          ~ "  writeln(msg);\n");
}

module module2;
import module1;
struct Foo
{
    int x;
    float y;
};

void main()
{
    module1.test!("Foo.x")("ok");
}

尝试编译失败并显示错误undefined identifier Foo.x,因为 Foo 在 module1 中不可见。有没有办法以在模块2而不是模块1中评估模板参数的方式重写它。如果这是不可能的,有没有办法获得一个代表“Foo.x”的对象并将其作为模板参数传递?(这不会解决一般情况,但至少会有用)。

4

1 回答 1

3

在调用站点传递类型,或使用模板的别名参数。模板别名参数是更通用的方法。有了这个,你传递了一个符号——不是名字,而是整个东西,所以它不需要在模板中进行范围查找——并使用它。同样,无需在这里混合:

module module1;
import std.stdio;
// alias field instead of string field...
// the static is needed too because otherwise dmd complains that Foo.x needs a this to be usable
static public void test(alias field)(string msg)
{
     // and then use it directly
    static if (__traits(isArithmetic, typeof(field) ))
          writeln(msg);
}

即使您正在混合生成的字符串代码,您也将始终使用本地名称字段,而不是字符串化名称。mixin(field.stringof) 将是一个错误,而只是 mixin("field")。

在使用点:

module module2;
import module1;
struct Foo
{
    int x;
    float y;
}

void main()
{
   // passing it without quotes
    module1.test!(Foo.x)("ok");
}
于 2013-11-04T00:24:27.963 回答