template parameter inference and introspection

John Colvin via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Feb 24 03:17:46 PST 2017


On Thursday, 23 February 2017 at 18:33:33 UTC, Meta wrote:
> On Thursday, 23 February 2017 at 18:21:51 UTC, Meta wrote:
>> On Thursday, 23 February 2017 at 16:01:44 UTC, John Colvin 
>> wrote:
>>> Is there any way to get a reference/alias to the 
>>> instantiation of a template function that would be called, 
>>> given certain parameters? I.e. to get the result of whatever 
>>> template parameter inference (and overload resolution) has 
>>> occurred?
>>>
>>> E.g. for some arbitrarily complex foo:
>>>
>>> static assert(__traits(compiles, foo(3)));
>>> alias fooWithInt = someMagic(foo(3));
>>>
>>> so if foo was `void foo(T)(T t) {}` then `fooWithInt` would 
>>> be `foo!int`, but if it was `void foo(Q = float, T = long)(T 
>>> t)` then `fooWithInt` would be `foo!(float, int)`
>>
>> I don't believe so, because foo(3) is a value (void), not a 
>> type like foo!int would be. You can't get it back after you've 
>> called the function. You would have to do something like:
>>
>> alias fooWithInt = someMagic!foo(3);
>>
>> Where someMagic constructs the alias to foo!int based on the 
>> type of arguments passed, or something like that.
>
> A quick and rough example I threw together. Annoyingly, I can't 
> figure out a way to tell the compiler that I want to printout 
> the symbol of fooWithInt, not call it without parens. The best 
> I can do is print out its type.
>
> void foo(T)(T t) {}
> void foo(Q = float, T = long)(T t) {}
>
> alias Typeof(alias v) = typeof(v);
>
> template getInstantiation(alias f, T...)
> {
>     import std.meta;
>
>     alias getInstantiation = f!(staticMap!(Typeof, T));
> }
>
> alias fooWithInt = getInstantiation!(foo, 3);
> alias fooWithLong = getInstantiation!(foo, 3L);
>
> void main()
> {
>     pragma(msg, typeof(fooWithInt));
>     pragma(msg, typeof(fooWithLong));
> }

Unfortunately that only works by accident of my example. A 
counterexample:

T foo(Q = float, T = short)(T t) { return t; }

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
     import std.meta;
	
     alias getInstantiation = f!(staticMap!(Typeof, T));
}

static assert(is(typeof(foo(3)) == int)); // ok
static assert(is(typeof(getInstantiation!(foo, 3)(3)) == int)); 
// fails



More information about the Digitalmars-d-learn mailing list