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; }