在D语言中,将模板函数作为参数传递给另一个模板函数

5

我正在尝试将D的sort函数作为模板参数发送到pipe函数。当我未使用模板参数时,sort函数可以正常工作:

import std.stdio,std.algorithm,std.functional;

void main()
{
    auto arr=pipe!(sort)([1,3,2]);
    writeln(arr);
}

然而,当我尝试在模板参数中使用sort时:
import std.stdio,std.algorithm,std.functional;

void main()
{
    auto arr=pipe!(sort!"b<a")([1,3,2]);
    writeln(arr);
}

我遇到了一个错误 - main.d(5): 错误: 模板实例sort!("b<a") sort!("b<a")与模板声明sort(alias less = "a < b",SwapStrategy ss = SwapStrategy.unstable,Range)不匹配 为什么会出现这种情况?sort!"b<a" 单独运行没有问题,而且它的参数和返回类型与sort相同,所以为什么pipe接受sort而不是sort!"b<a"?是否有正确的语法来执行我尝试的操作?
更新:
好的,我尝试了一下包装sort函数。以下代码可以工作:
import std.stdio,std.algorithm,std.functional,std.array;

template mysort(string comparer)
{
    auto mysort(T)(T source)
    {
        sort!comparer(source);
        return source;
    }
}

void main()
{
    auto arr=pipe!(mysort!"b<a")([1,3,2]);
    writeln(arr);
}

那么为什么原始版本不起作用呢?这是因为sort需要额外的模板参数吗?
1个回答

5
是的,这是因为有额外的模板参数,具体来说是“Range”参数。问题可以简化为:
size_t sort2(alias f, Range)(Range range)
{
    return 0;
}
alias sort2!"b<a" u;

实例化sort!“b<a”将失败,因为范围未确定。函数调用sort2!“b<a”([1,2,3])有效,因为参数[1,2,3]可以告诉编译器类型范围是int []。这被称为“隐式函数模板实例化(IFTI)”。但是,IFTI仅在用作函数时才起作用。在您的用例中,sort!“b<a”在没有提供所有参数的情况下被实例化,因此出现错误。

通过使输入成为函数文字,可以解决此问题,这与您的mysort解决方案类似:

 auto arr = pipe!(x => sort!"b<a"(x))([1,3,2]);

或者你可以提供所有所需的模板参数。不过这将使代码非常难以阅读。
auto arr = pipe!(sort!("b<a", SwapStrategy.unstable, int[]))([1,3,2]);

我明白了...我想到那个隐式将参数类型作为模板参数的 pipe 模板应该将该参数传递给第一个管道函数,但我发现事实并非如此。 - Idan Arye
@IdanArye:pipe永远无法做到这一点,因为可以将其与参数分开(alias pipe!(f) piped;,然后许多行后piped([1,2,3]);)。 - kennytm
这样的别名操作难道不应该使得 piped 本身成为一个带模板参数的函数吗? - Idan Arye

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接