about lambdas
Timon Gehr
timon.gehr at gmx.ch
Wed Jan 2 15:24:02 PST 2013
On Wednesday, 2 January 2013 at 21:12:33 UTC, Maxim Fomin wrote:
> On Wednesday, 2 January 2013 at 21:00:10 UTC, Michael wrote:
>> R With(I, R)(I o, R function (I) fun)
>> {
>> static if(isAssignable!(I, typeof(null)))
>> return o is null ? null : fun(o);
>> else
>> return fun(o);
>> }
>>
>> ...
>>
>> in main function
>> ----------------
>> foreach(p; persons)
>> p.With((Person x) => x.address); // works
>>
>> but
>> ----------------
>> foreach(p; persons)
>> p.With(x => x.address); // error
>>
>> nullcheck.d(89): Error: template maybe.With does not match any
>> function template
>> declaration. Candidates are:
>> maybe.d(20): maybe.With(I, R)(I o, R function(I) fun)
>> nullcheck.d(89): Error: template maybe.With(I, R)(I o, R
>> function(I) fun) cannot
>> deduce template function from argument types !()(Person,void)
>>
>>
>> Why?
>
> The first one is a lambda function, the second one is a lambda
> template. Templates have type void.
Actually the 'void' is just a diagnostics bug. (lambda templates
only exist in template parameter lists.) The reason the matching
fails is that IFTI is not smart enough to devise a type for the
parameter 'x', and therefore no type for 'R' is obtained, what
makes the matching fail. Currently other parameters are not taken
into account during IFTI matching. I believe that the reason is
that otherwise the compiler needs to be clever about the order in
which it analyzes the parameters. I consider this one of the more
annoying limitations.
A workaround that should work in this case is to use a template
parameter:
auto With(alias fun, I)(I o) // maybe add a template constraint
here
{
static if(isAssignable!(I, typeof(null)))
return o is null ? null : fun(o);
else
return fun(o);
}
---
foreach(p; persons)
p.With!(x => x.address);
This creates a template from the lambda, and instantiates it once
inside 'With'. This way the return type does not have to be part
of the template parameters.
More information about the Digitalmars-d
mailing list