Fun with templates
Artur Skawina
art.08.09 at gmail.com
Sat Jul 6 08:05:35 PDT 2013
On 07/06/13 13:35, Manu wrote:
> The point here is that I want more control over the signature of the instantiated template (reduce the number of permutations generated for various calls). Template blow-out is perhaps the biggest and most well known day-to-day problem in C++, and tools like this may be very valuable to mitigate the disaster.
I was going to reply that while template bloat is a real issue, it is the
compiler that should deal with this (by always inlining trivial function).
Then I remembered that you mentioned that you want this only for "primitive"
types, and realized what your real problem is. IFTI and value types.
For example:
auto f(T...)(T a) {/*...*/}
int a;
const int b;
immutable int c;
f(a);
f(b);
f(c);
This creates three instances of 'f'. And it gets much worse with a
larger number of arguments... Typically all instantiations will be
identical, except in cases where the 'f' implementation tries to
mutate the argument(s). (This mutation is always safe when T is
passed by value and T does not contain external references)
IFTI should just strip the qualifiers from all value-passed POD types
which contain no refs (ie no pointers, slices and classes inside). Doing
that will significantly reduce template bloat, at practically no
cost. It *is* a change in behavior, but there shouldn't be much code
out there that sensibly relies on the 1:1 type propagation. Explicitly
specifying a type will still be possible using 'typeof'.
Note that this is already done for pointers; calling 'f' with
the following:
immutable(void)* a;
const immutable(void)* b;
immutable immutable(void)* c;
will not create three separate instances.
This is possible in the pointer case because the compiler can get away
with manipulating the type. Doing this for structs would be more
complicated; fixing the primitive types- (and maybe PODs) case isn't.
BTW, the way D's 'auto' works contributes to the problem:
const int a;
auto b = a+a;
auto c = a+1;
f(b);
f(c);
uses two different 'f' instances.
artur
More information about the Digitalmars-d
mailing list