2015-11-01 49 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)