2013-11-03 52 views
2

在D中,模板实例化在mixin出现的范围内进行计算,而不是在定义模板声明的位置。在mixin出现的范围内,可以使用模板mixin来评估身体。 但是我有什么可以做的时候我有一个模板函数,我希望它的主体在调用范围内进行评估?我无法找到一种方式将其翻译成相当的东西。D中的模板实例化理解模板,模板混合模板,模板函数和范围

让我们有两个模块,module1module2下面的例子:

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是不是里面模块1可见。有没有一种方法可以用模块参数在模块2中而不是模块1中进行评估的方式进行重写。 如果这是不可能的,有没有办法获得一个代表“Foo.x”的对象并将其作为模板参数传递? (这不会解决一般情况,但至少会有用)。

回答

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

即使你是在生成的字符串代码混合,你总是使用本地名,字段,而不是stringized名。 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"); 
} 
+0

是的,这似乎正是我一直在寻找。我来到了类似的解决方案,使用类的模板参数,并保持字段的字符串,但是好得多。谢谢。 –