D 函数模板和类型推断
考虑以下代码:
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
}
现在,我希望编译器推断 consume
将被实例化,
string consume!(string)(string, Regex!(char))
但这似乎并没有发生。错误如下:
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))
我发现参数类型是正确的...我尝试了函数签名的一些变体,例如:
S consume (S) (Regex ! ( Unqual!(typeof(S.init[0])) ) rg, ref S data)
它也不能编译(想法是更改参数的顺序),并且
immutable(S)[] consume (S) (Regex ! ( S ) rg, ref immutable(S)[] data)
它编译并推断类型正常。如果我在调用中显式指定类型,即
consume!string(data, rx);
它也会编译并且调试 writeln
打印 char
,正如预期的那样。我是否在推理规则中遗漏了某些内容,或者我刚刚遇到了编译器中的错误?
哦是的:
$ dmd -v
DMD64 D Compiler v2.053
...
Consider the following code:
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
}
Now, I expect the compiler to infer that consume
is to be instantiated as
string consume!(string)(string, Regex!(char))
but that doesn't seem to happen. The errors are as follows:
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))
and I see that the parameter types are correct... I've tried some variations of function signature, like:
S consume (S) (Regex ! ( Unqual!(typeof(S.init[0])) ) rg, ref S data)
which doesn't compile also (the idea was to change the order of arguments), and
immutable(S)[] consume (S) (Regex ! ( S ) rg, ref immutable(S)[] data)
which compiles and infers the types alright. If I specify the type explicitly in the call, i.e.
consume!string(data, rx);
it also compiles and the debug writeln
prints char
, just as expected. Am I missing something in the inference rules, or I've just hit a bug in the compiler?
Oh yes:
$ dmd -v
DMD64 D Compiler v2.053
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不能说这是否是一个错误,但这里有一个解决方法,它不会强制您指定类型或更改参数的顺序。将
consume
的签名更改为:I can't say if it's a bug, but here's a workaround which doesn't force you to specify the type or change the order of arguments. Change
consume
's signature to: