2015-03-02 52 views
4

是否有可能爲mixin模板中的函數生成名稱?事情是這樣的:Mixin的名稱參數化與模板參數

mixin template Generator(string name) 
{ 
    @property void mixin(name) pure nothrow // mixin(name) is not valid :(
    { 
      //some cool stuff here 
    } 
} 
+0

我知道我可以做的東西與混入,但沒有代碼高亮顯示的字符串中的d而且很難調試這樣的代碼。 – 2015-03-02 17:15:50

+1

您可能想嘗試'q {code here}'字符串樣式。它們經常被強調,儘管它對調試沒有多大幫助。 – 2015-03-02 21:49:35

回答

4

我希望有人能想出一些清潔劑,但這種應該做你想要什麼:

mixin template Generator(string name) 
{ 
    mixin("alias " ~ name ~ " = _fun;"); 
    @property void _fun pure nothrow 
    { 
     //some cool stuff here 
    } 
} 

這不幸注入_fun到局部名字空間以及,但如果您多次使用Generator,則任何撥打_fun的電話都將被拒絕,因爲它們不明確。如果您合法地在別處定義了名爲_fun的函數,這可能會成爲問題。

雖然你生成多個_funs,通過Generator創建別名放在電話是一點也不含糊,因爲他們是指_fun由特定的模板實例作用域:

mixin Generator!"foo"; 
mixin Generator!"bar"; 

foo(); // not ambiguous, calls Generator!"foo"._fun 
bar(); // not ambiguous, calls Generator!"bar"._fun 
_fun(); // ambiguous, rejected by compiler 

編輯:只是想扔了另瘋狂的想法我有:

mixin template Generator(names ...) { 
    @property void opDispatch(string s)() pure nothrow { 
    foreach(name ; names) { 
     static if (s == name) { 
     // do stuff 
     } 
    } 
    } 
} 

struct Foo { 
    mixin Generator!("hello", "goodbye"); 
} 

void main() { 
    Foo foo; 

    foo.hello; 
    foo.goodbye; 
} 

這避免產生垃圾_fun,但它確實需要您的類尚未定義opDispatch。此外,它不能在同一個類中多次使用(不能在同一個作用域中從不同的mixin模板重載相同的方法),您必須調用它一次,並將所有名稱作爲參數傳入。但是,如果您想一次性發送所有名稱,但尚未定義opDispatch,則可能會更好。

+0

不錯,謝謝。但是我忘記提及用例是多次使用這種「發生器」,並且名稱不同。無論如何,你的解決方案是有用的其他任務=) – 2015-03-02 18:08:35

+0

請相應地編輯您的問題,這太相關;-) – menjaraz 2015-03-02 18:26:35

+1

@DenisGladkiy,'發電機'可以使用多個名稱,請參閱上面的編輯。我實際上有點驚訝,這工作:) – rcorre 2015-03-02 20:14:20

2

您可以使用替換在編譯時隱藏可怕串連做一些串掛羊頭賣狗肉:

mixin(replace(q{ 
    @property void mixin(name) pure nothrow 
    { 
      //some cool stuff here 
    } 

}, q{mixin(name)}, name));