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
...
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:
S consume (S, U) (ref S data, Regex!U rg) if (is(U == Unqual!(typeof(S.init[0]))))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With