Return 来自模板的动态 AliasSeq

Return dynamic AliasSeq from template

我正在尝试编写一个模板,它将 return return 类型的 AliasSeq 来自 AliasSeq 函数。但是在我尝试编译它的代码中,它告诉我 Error: type (...) has no value

这是我目前的代码:

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 的类型,因为该函数本身用于查找类型,因此我可以在其他地方使用它。

一旦定义了 alias,就不能修改它。您也不能从函数中 return AliasSeqs,因为它们不是 first-class 值。

正确的方法是通过递归模板...

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

这听起来很适合 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)