Proposal: static template(fail)

Janice Caron caron800 at googlemail.com
Thu Dec 13 09:30:28 PST 2007


On 12/13/07, Jason House <jason.james.house at gmail.com> wrote:
> Janice Caron Wrote:
>
> > On 12/13/07, Aziz K. <aziz.kerim at gmail.com> wrote:
> > > Why not use a static assert: static assert(0, "Substitution Failure");
> >
> > A static assert is a compile error. Different thing. What you want is
> > for the template not to be instanted, not for it to be instantiated
> > with a compile error.
> >
> > Put it another way. Suppose you write
> >
> >     S(int) s;
> >
> > Which would you prefer - an error message saying that s couldn't be
> > instantiated (giving the filename and line number of the above line),
> > or an error message saying that a static assert in the middle of some
> > library file had been hit?
>
> I'd prefer a static assert.
> As with all errors, I'd want a backtrace.

You're missing the point, which is IT'S NOT AN ERROR. It's a
substitution failure - and substitution failure IS NOT AN ERROR.
That's a basic principle of template programming.

Look, right now you can do:

    template A(T:U) { /*code*/ }
    template A(T:V) { /*the same code*/ }
    template A(T:W) { /*the same code*/ }
    template A(T:X) { /*the same code*/ }
    template A(T:Y) { /*the same code*/ }

but you can't simplify it as:

   template A(T:U|V|W|X|Y)

What you /could/ do is:

   template A(T)
   {
        static if(is(T:U) | is(T:V) | is(T:W) | is(T:X) | is(T:y))
        {
            /*code*/
        }

but you can't take the obvious next step of

       else substitution failure

...you have to make it an actual error. Template specialisation is a
powerful tool in metaprogramming, but right now we have to use
multiple specialisations in order to use it. We've got "static if" to
move us away from that antiquated C++ model, but still the only way to
generate a substitution failure is to go back to that model.

Note that an alternative way to achieve much the same thing would be
to extend the syntax of specialisation to include something like

    (T:if(expression))

where the specialisation is deemed to hold if the expression evaluates
to true at compile time. I quite like that - but I like my first
suggestion more. (Of course, they're not mutually exclusive).



> Functions currently have in/body/out sections.  I wouldn't mind seeing something like an "in" function for templated objects.

Right - so like my second suggestion:

    template A(T:if(someTest!(T)))

> To me, that's much more generic.

I'd say they're equivalent. It's just a question of whether you like
to read if/else style code, or multiple specialisation style code.


> In a world without backtraces for errors, it'd also allow a hint to the compiler that it should point the finger at the code that caused the instantiation.

Well, obviously we want backtraces for instantiation errors. But
that's as well, not instead of! :-)



More information about the Digitalmars-d mailing list