2015-11-01 55 views
2

我正在嘗試編寫一個模板,它將返回AliasSeq函數的返回類型的AliasSeq。然而,在我的代碼,當我嘗試編譯它,它告訴我Error: type (...) has no value從模板返回動態AliasSeq

這是我的代碼,我到目前爲止有:

template ReturnTypesFromFunctions(Functions...) 
{ 
    auto ReturnTypesFromFunctions() 
    { 
     alias functions = AliasSeq!(); 
     foreach(fn; Functions) 
     { 
      functions = AliasSeq!(functions, ReturnType!fn); 
     } 
     return functions; 
    } 
} 

基本上我試圖做的是自動生成從AliasSeq陣列這樣的:

int a(); 
bool b(); 
double c(); 

alias functions = AliasSeq!(a, b, c); 
alias returnTypes = ReturnTypesFromFunctions!functions; 
// returnTypes -> AliasSeq [int, bool, double] 

但與當前的代碼會導致這些錯誤:

Error: type (int) has no value 
Error: type (bool) has no value 
Error: type (double) has no value 
Error: type() has no value 

它可能與auto有關,因爲編譯器無法從函數別名中找到類型。然而,沒有類型可以代表AliasSeq,因爲函數本身用於查找類型,所以我可以在別處使用它。

回答

4

一旦你定義了alias,你就不能修改它。您也不能從函數返回AliasSeq,因爲它們不是一流的值。

要做到這一點是通過遞歸模板的正確方法...

template ReturnTypesFromFunctions(Funcs...) { 
    static if(Funcs.length == 0) 
     alias ReturnTypesFromFunctions = AliasSeq!(); 
    else 
     alias ReturnTypesFromFunctions = AliasSeq!(ReturnType!(Funcs[0]), ReturnTypesFromFunctions!(Funcs[1..$])); 
} 

...然而,在這種情況下,你只是重新發明staticMap模板,所以只使用來代替。

alias returnTypes = staticMap!(ReturnType, functions); 
+0

哦如果無法在使用的foreach我想我還需要重寫我的所有其他職能則是無效 – WebFreak001

3

這聽起來像一個很好用的staticMap

import std.meta, std.traits; 

template ReturnTypesFromFunctions(Functions...) { 
    alias ReturnTypesFromFunctions = staticMap!(ReturnType, Functions); 
} 

int a(); 
bool b(); 
double c(); 

alias functions = AliasSeq!(a,b,c); 
alias returnTypes = ReturnTypesFromFunctions!functions; 

pragma(msg, returnTypes); // (int, bool, double)