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 can't find the Bugzilla entry right now, but we discussed before why it is not generally possible to deduce A from a match of type B with Template!A. Basically you'd need the inverse of the Template and the type mapping would need to be bijectiv.

What does work though and looks similar is to deduce A from a match of Template!B with Template!A.

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*.

There is a linker optimization that would get rid of the duplicates.
http://stackoverflow.com/questions/15168924/gcc-clang-merging-functions-with-identical-instructions-comdat-folding

I came up with "out-of-bound" template instantiations to avoid unneeded instantiations. What you do is to forward common template code to another template that is next to the actual template. The next to is important because it allows to merge identical instantiations. For example this idiom is useful when you pass additional arguments to your template, e.g. __FILE__ and __LINE__.

void _f(T)(T a) {}
void f(T)(T a) { return _f!(Unqual!T)(a); }

template _f(CommonArgs) { enum _f = foo!CommonArgs; }
template f(CommonArgs, MoreArgs) { static assert(bar!MoreArgs); enum f = _f!CommonArgs; }

Reply via email to