D功能模板和类型推断

vin*_*nes 5 type-inference d function-templates

请考虑以下代码:

module ftwr;

import std.regex;
import std.stdio;
import std.conv;
import std.traits;

S consume (S) (ref S data, Regex ! ( Unqual!(typeof(S.init[0])) ) rg)
{
    writeln (typeid(Unqual!(typeof(S.init[0]))));

    auto m = match(data, rg);
    return m.hit;
}

void main()
{
    auto data = "binary large object";
    auto rx = regex(".*");
    consume (data, rx); // this line is mentioned in the error message
}
Run Code Online (Sandbox Code Playgroud)

现在,我希望编译器推断出consume要实例化为

string consume!(string)(string, Regex!(char))
Run Code Online (Sandbox Code Playgroud)

但这似乎不会发生.错误如下:

func_template_with_regex.d(24): Error: template ftwr.consume(S) does not match any function template declaration
func_template_with_regex.d(24): Error: template ftwr.consume(S) cannot deduce template function from argument types !()(string,Regex!(char))
Run Code Online (Sandbox Code Playgroud)

我看到参数类型是正确的...我已经尝试了一些函数签名的变体,如:

S consume (S) (Regex ! ( Unqual!(typeof(S.init[0])) ) rg, ref S data)
Run Code Online (Sandbox Code Playgroud)

也没有编译(想法是改变参数的顺序),和

immutable(S)[] consume (S) (Regex ! ( S ) rg, ref immutable(S)[] data)
Run Code Online (Sandbox Code Playgroud)

编译和推断类型正好.如果我在调用中明确指定类型,即

consume!string(data, rx);
Run Code Online (Sandbox Code Playgroud)

它也编译和调试writeln打印char,就像预期的那样.我在推理规则中遗漏了什么,或者我刚刚在编译器中遇到了一个错误?

哦是的:

$ dmd -v
DMD64 D Compiler v2.053
...
Run Code Online (Sandbox Code Playgroud)

Vla*_*eev 5

我不能说这是不是一个bug,但是这里有一个解决方法,它不会强制你指定类型或改变参数的顺序.将consume签名更改为:

S consume (S, U) (ref S data, Regex!U rg) if (is(U == Unqual!(typeof(S.init[0]))))
Run Code Online (Sandbox Code Playgroud)