D中的模板参数推断

时间:2012-03-05 23:15:46

标签: templates d

我正在编写一些矢量函数,这些函数在静态D数组上运行,如下所示:

real[N] unit(uint N)(real[N] v) {
    real[N] u = (v[] / norm(v)); //explicit type necessary to force slice-operator
    return u;                    //to return static-length array
}

real[3] v = unit!(3)([1,2,3]);   //works
real[3] w = unit([1,2,3]);       //error, compiler doesn't infer the template parameter
real[3] x = [1,2,3];
auto i = unit(x);                //also works, forces statically allocated array

所以,我的问题是,如果我将文字数组直接传递给函数,有没有办法让编译器推断模板参数N?我尝试使用“1.0L”格式,希望数组是从int或float的静态数组中转换出来的,但这也不起作用。 TL; DR我可以让上面的例子(w)在上面工作吗?谢谢!

编辑:为了澄清,我尝试了一些使用专门模板参数的变体,但我不确定我是否已正确完成。我也在调用中尝试new real[3]([1,2,3])来强制堆分配的静态数组(三角麒麟?)但我无法编译。

2 个答案:

答案 0 :(得分:3)

问题是[1,2,3]不是静态数组。它是一个动态数组,因此它不能匹配。这是错误的类型,并且没有办法获得静态数组文字。如果要将数组文字作为静态数组传递,则需要先将其赋值给变量,或者将其转换为所需的类型。

auto w = unit(cast(real[3])[1,2,3]);

应该有效。就个人而言,我认为最好只是明确地实例化模板

auto w = unit!3([1, 2, 3]);

因为它避免了搞砸演员的风险。

现在,我认为有一个明确的论点,编译器应该只适用于这种情况,但它往往比使用普通函数更容易使用模板,因为它通常实例化具有您传递的确切类型的模板尝试进行任何隐式转换,而普通函数会隐式地将动态数组转换为静态数组。随意open an enhancement request。行为可能会改变。它最近被 更改,因此IFTI(隐式函数模板实例化)实例化了一个数组的尾部const版本(例如immutable(char)[]而不是immutable(char[])),这是一个明确的改进。现在,这与尝试转换有点不同(我相信编译器只是自动执行,总是将数组视为IFTI的tail-const),所以我不知道在这种情况下获得编译器行为改变的几率非常高高。但问问题并没有什么坏处。

答案 1 :(得分:2)

思想/劈:

real[T.length] unit(T...)(T t)
{
    real[T.length] v,u;
    foreach(i,x; t) v[i] = x;
    u[] = (v[] / norm(v));
    return u;
}

void main()
{
    real[3] v = unit(1,2,3);
}

可能不会像使用real[3] v = unit!3([1,2,3])一样快,因为那里有foreach,但我猜想。 args也会在运行时转换为实数。 HM。