Fallback 'catch-all' template functions

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Thu Sep 1 09:50:49 PDT 2016


On 9/1/16 1:37 AM, Manu via Digitalmars-d wrote:
> So, consider a set of overloads:
>
>   void f(T)(T t) if(isSomething!T) {}
>   void f(T)(T t) if(isSomethingElse!T) {}
>   void f(T)(T t) {}
>
> I have a recurring problem where I need a fallback function like the
> bottom one, which should be used in lieu of a more precise match.
> This is obviously an ambiguous call, but this is a pattern that comes
> up an awful lot. How to do it in D?
>
> I've asked this before, and people say:
>
>   void f(T)(T t) if(!isSomething!T && !isSomethingElse!T) {}
>
> Consider that more overloads are being introduced by users spread out
> across many modules that define their own kind of T; this solution is
> no good.

I agree. Note that if(isSomethingElse!T) may also need to have 
if(!isSomething!T && isSomethingElse!T).

A suggestion in the past was to allow "else" clauses with if 
constraints. I had envisioned:

void f(T)(T t) if(isSomething!T) {}
void f(T)(T t) else if(isSomethingElse!T) {}
void f(T)(T t) else {}

But someone also suggested this more DRY solution as well (can't 
remember the thread for it):

void f(T)(T t) if(isSomething!T) {}
           else if(isSomeghingElse!T) {}
           else {}

Obviously this doesn't work across modules, but how does that even work? 
You need some sort of ordering for an if/else if/else scheme to work.

Having a "fallback" template could potentially define a way to handle 
the default, but it doesn't fix the other issues.

I don't know if it's because of the current rules, or just natural, but 
typically I'm not splitting my template functions between many modules.

-Steve


More information about the Digitalmars-d mailing list