2013-11-03 93 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

是的,這似乎正是我一直在尋找。我來到了類似的解決方案,使用類的模板參數,並保持字段的字符串,但是好得多。謝謝。 –