Templates - Numeric Types only

Jeremie Pelletier jeremiep at gmail.com
Fri Aug 7 20:49:57 PDT 2009


Andrei Alexandrescu Wrote:

> Jarrett Billingsley wrote:
> > On Thu, Aug 6, 2009 at 9:53 PM, Andrei
> > Alexandrescu<SeeWebsiteForEmail at erdani.org> wrote:
> >> Jarrett Billingsley wrote:
> >>> On Thu, Aug 6, 2009 at 9:19 PM, Andrei
> >>> Alexandrescu<SeeWebsiteForEmail at erdani.org> wrote:
> >>>> Kevin wrote:
> >>>>> Hi,
> >>>>> simple Question:
> >>>>> Is it possible to allow just numeric types in templates?
> >>>>> For example to create a Vector Class like this:
> >>>>>
> >>>>> class Vector(T:"numeric" = float, int size = 4)
> >>>>>
> >>>>> Thanks,
> >>>>> Kevin
> >>>> import std.traits;
> >>>>
> >>>> class Vector(T, int size = 4) if (isNumeric!T)
> >>>> {
> >>>>   ...
> >>>> }
> >>> Unfortunately,
> >>>
> >>> struct Vec(T) if(isNumeric!T) {}
> >>> struct Vec(T) {}
> >>> Vec!(int) x; // error
> >>>
> >>> foo.d(14): Error: template instance Vec!(int) matches more than one
> >>> template declaration, Vec(T) if (isNumeric!(T)) and Vec(T)
> >>>
> >>> *sigh*
> >>>
> >>> Wouldn't it be nice.
> >> struct Vec(T) if(isNumeric!T) {}
> >> struct Vec(T) if(!isNumeric!T) {}
> >>
> >> is actually superior because it's more modular; the semantics of the latter
> >> does not depend on the presence of the former.
> > 
> > But the condition of the latter now depends on the condition of the
> > former.  And on the condition of any other 'specializations':
> > 
> > struct Vec(T) if(isNumeric!T) {}
> > struct Vec(T) if(isSomeString!T) {}
> > struct Vec(T) if(!isNumeric!T) {} // uhoh
> > Vec!(string) x; // matches two
> > 
> > Now the fallback has to be declared as
> > 
> > struct Vec(T) if(!isNumeric!T && !isSomeString!T) {}
> > 
> > and it gets worse the more you add.
> 
> I know, and I explained why that's arguably better.
> 
> Andrei

I for myself favor lots of small templates to keep function declarations shorter, for example:

template isStringOrNumeric(T) {
    enum isStringOrNumeric = isSomeString!T || isNumeric!T;
}
struct Vec(T) if(isSomeString!T) {}
struct Vec(T) if(isNumeric!T) {}
struct Vec(T) if(!isStringOrNumeric!T) {}

It also allows for the templates to have static asserts of their own to make bugs easier to isolate, and they can be moved to another file which makes for more generic programming. Chances are you'll be using the template again if you need it here.

I usually try to keep my template if statements down to one or two short expressions at most, otherwise it quickly becomes more confusing than useful.



More information about the Digitalmars-d mailing list