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