On 6 July 2013 11:45, Timon Gehr <timon.gehr@gmx.ch> wrote:
On 07/06/2013 03:34 AM, 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*.

void f(T)(const(T) a) {}

This will strip off const, immutable and inout, but not shared.

I'd have thought that

void f(T)(const(shared(T)) a) {}

would strip shared as well, but DMD does not match int to const(shared(int)) at all which I think is incorrect.

So what is the signature of f() in this case? It looks like the function receives const(T), not T.
It looks like it sets T to Unqual!T, but it's not T that I'm interested in, it's the function argument being deduced to the correct type.

We can do impressive stuff like this:
  void f(T : U[N], U, size_t N)(T x); .. but I suppose in that example, T is still the supplied type verbatim, it's just performing a lot of fancy work to decompose it.

So then I wonder if my question becomes, with parameter type deduction, is it an absolute requirement that the parameter type is taken to be the supplied argument's type verbatim (and not possibly something it is implicitly castable to)?
Is there ANY way to flex this rule while retaining the functionality of argument type deduction?