Fun with templates

monarch_dodra monarchdodra at gmail.com
Sat Jul 6 01:42:44 PDT 2013


On Saturday, 6 July 2013 at 01:35:09 UTC, Manu wrote:
> Okay, so I feel like this should be possible, but I can't make 
> it work...
> I want to use template deduction to deduce the argument type, 
> but I want
> the function arg to be Unqual!T of the deduced type, rather 
> than the
> verbatim type of the argument given.
>
> I've tried: void f(T : Unqual!U, U)(T a) {}
> and: void f(T)(Unqual!T a) {}
>
> Ie, if called with:
>   const int x;
>   f(x);
> Then f() should be generated void f(int) rather than void 
> f(const int).
>
> I don't want a million permutations of the template function 
> for each
> combination of const/immutabe/shared/etc, which especially 
> blows out when
> the function has 2 or more args.
>
> Note: T may only be a primitive type. Obviously const(int*) can 
> never be
> passed to int*.

You could just forward to an implementation template, passing 
explicitly the arguments. This is kind of like the "take" 
function making an explicit call to "Take!T" I guess. In any 
case, this is what I mean.

--------
void foo(T)(T t)
{
     fooImpl!(Unqual!T)(t);
}
void fooImpl(T)(T t)
{
     static assert(is(Unqual!T == T));
     //do it
}

void main()
{
     const(int) x;
     foo(x);
}
--------

This should do what you want. foo should be completly inlined 
away I believe. It is a tiny bit hackish, but should work. You'll 
generate all flavors of foo, but only Unqual'd versions of 
fooImpl (which is what you care about). You can also add some 
"isPrimitivee!T" if you want or something.

Not sure how this deals with "shared" ? In any case, you asked 
for "Unqual", so that's what you get ;)


More information about the Digitalmars-d mailing list