template instantiation --- having trouble therewith

John Colvin john.loughran.colvin at gmail.com
Thu Sep 5 02:00:26 PDT 2013


On Tuesday, 3 September 2013 at 11:51:37 UTC, Carl Sturtivant 
wrote:
>>
>> I'm confused as to what you're trying to do... your example 
>> code is equivalent to
>>
>>  import std.stdio;
>>  int x = 3;
>>  int scale( int s) { return x * s; }
>>  auto f = &scale;
>>  writeln( f(7) );
>
> No it isn't according to dmd.
>
> My code is a minimal piece that produces the same error as some 
> real code. The higher order generic function muddle in the real 
> code is supposed to transform one delegate into another, but I 
> still get the template problem if muddle is the identity 
> function (given here).
>
> My example code isn't equivalent to the above according to the 
> compiler. Why is that? And how can I make it work?

Ok, that makes more sense.

The reason why it doesn't work is that you're effectively asking 
the compiler to work backwards from {the type of the delegate 
passed to muddle} to {the type parameters that would have to be 
used in Dptr to generate that delegate type}.
I'm no expert on type-deduction algorithms, but I seriously doubt 
that's a solvable problem in the general case, especially 
considering that the definition of Dptr could contain string 
mixins etc.   In the general case, all code is forwards-only.

Anyhow, it's easy to work around:

import std.traits : ReturnType, ParameterTypeTuple;

template Dptr( T, U...) {
	alias T delegate( U args) Dptr;
}

auto muddle( DT)( DT f) {
	alias T = ReturnType!f;
	alias U = ParameterTypeTuple!f;
	//use T and U
	return f; //or make another delegate in real code
}


unittest {
	import std.stdio;
	int x = 3;
	int scale( int s) { return x * s; }
	Dptr!(int,int) f = muddle( &scale);
	writeln( f(7));
}


More information about the Digitalmars-d-learn mailing list