Reducing template constraint verbosity? [was Re: Slides from my ACCU Silicon Valley talk]

Steven Schveighoffer schveiguy at yahoo.com
Tue Dec 14 08:08:04 PST 2010


On Tue, 14 Dec 2010 10:47:05 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 12/14/10 7:33 AM, biozic wrote:

>> I have a question about this and some pieces of code in the standard
>> library, notably std.algorithm: some of the templated functions use
>> template constraints even when no template overloading is taking place.
>> Wouldn't some static asserts help print more accurate messages when
>> these functions are misused?
>>
>> Nicolas
>
> The intent is to allow other code to define functions such as e.g. "map"  
> or "sort". Generally any generic function should exclude via a  
> constraint the inputs it can't work on. That way no generic function  
> chews off more than it can bite.

Redirected from another thread.

Having written a few of these functions with template constraints, I  
wondered if there was ever any discussion/agreement on reducing verbosity  
when specializing template constraints?

For instance, if you want two overloads of a template, one which accepts  
types A and one which accepts types B where B implicitly converts to A  
(i.e. a specialization), you need to explicitly reject B's when defining  
the overload for A's.  For example:


void foo(R)(R r) if(isRandomAccessRange!R) {...}

void foo(R)(R r) if(isInputRange!R && !isRandomAccessRange!R) {...}


It seems redundant to specify !isRandomAccessRange!R in the second  
overload, but the compiler will complain otherwise.  What sucks about this  
is the 'definition' of the first overload is partially in the second.   
That is, you don't really need that clause in the second overload unless  
you define the first one.  Not only that, but it makes the template  
constraints grow in complexity quite quickly.  Just look at a sample  
function in std.array that handles 'the default' case:


void popFront(A)(ref A a) if(!isNarrowString!A && isDynamicArray!A &&  
isMutable!A && !is(A == void[]))

Any idea how this can be 'solved' or do we need to continue doing things  
like this?  My naive instinct is to use the declaration order to determine  
a match (first one to match wins), but that kind of goes against other  
overloads in D.

-Steve


More information about the Digitalmars-d mailing list