Fallback 'catch-all' template functions

Marco Leise via Digitalmars-d digitalmars-d at puremagic.com
Sat Sep 3 13:52:17 PDT 2016


Am Sat, 3 Sep 2016 14:24:13 +0200
schrieb Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>:

> On 9/3/16 7:29 AM, Manu via Digitalmars-d wrote:
> > On 3 September 2016 at 11:38, Andrei Alexandrescu via Digitalmars-d
> > <digitalmars-d at puremagic.com> wrote:  
> >> On 9/3/16 2:41 AM, Manu via Digitalmars-d wrote:  
> >>>
> >>> On 3 September 2016 at 00:18, Xinok via Digitalmars-d
> >>> <digitalmars-d at puremagic.com> wrote:  
> >>>>
> >>>>
> >>>> In the past, I have suggested using the "default" keyword to specify a
> >>>> fallback function of this kind. I think it's a useful pattern for generic
> >>>> algorithms that have optimized variants on specific types for
> >>>> performance.
> >>>>
> >>>>    void f(T)(T t) if(isSomething!T) {}
> >>>>    void f(T)(T t) if(isSomethingElse!T) {}
> >>>>    void f(T)(T t) default {}  
> >>>
> >>>
> >>> It's an interesting idea... flesh out a DIP?  
> >>
> >>
> >> We're better off without that. -- Andrei  
> >
> > Then we need a decent way to do this.  
> 
> Use static if inside the function. The entire notion of "call this 
> function if you can't find something somewhere that works" is 
> questionable. -- Andrei

This notion is what drives template specializations in D:

char foo(T)(T t) { return '?'; } // Call this if nothing else matches
char foo(T : int)(T t) { return 'i'; } // Call this for ints
char foo(T : string)(T t) { return 's'; } // Call this for strings

Granted it's a bit more fuzzy and talks about "more
specialized", but it is ultimately the same as a hard fallback
when foo(3.4) is called.

UFCS functions are also only invoked if there is no method
with that name on the type, or any type reachable through
"alias this" or opDot and there is no opDispatch on
said types accepting that name.

However questionable the notion is, it is common in D today.

Static if also wont work in cases where the signature needs to
be different, like overloads of opCast, where one returns bool
and is const and another returns a different view on the same
thing by ref and is inout. opCast(T:bool) would be unclean, as
it also matches types T with a boolean 'alias this'.
One can also imagine that some overloads want to take their
arguments by value while others take it by ref.

-- 
Marco



More information about the Digitalmars-d mailing list