TDPL: Overloading template functions

Andrej Mitrovic andrej.mitrovich at gmail.com
Fri Jul 30 13:25:50 PDT 2010


Okay take a look at this:

import std.stdio;

void main()
{
}

T[] find(T, E)(T[] haystack, E needle)
    if (is(typeof(haystack[0] != needle) == bool))
{
    while (haystack.length > 0 && haystack[0] != needle) {
        haystack = haystack[1 .. $];
    }
    return haystack;
}


T1[] find(T1, T2)(T1[] longer, T2[] shorter)
    if (is(typeof(longer[0 .. 1] == shorter) : bool) && false)
{
    while (longer.length >= shorter.length) {
        if (longer[0 .. shorter.length] == shorter)
            break;
        longer = longer[1 .. $];
    }
    return longer;
}

unittest {
    string[] longer = ["one", "two"];
    string shorter = "two";
    find(longer, shorter);

    writeln(is(typeof(longer[0 .. 1] == shorter) : bool) && false); //
writes false
}

I'm tyring to make the code in the unittest use the first templated
function. But it will fail because DMD matches the call to find to the
second templated function. But it should never match the second template,
I've forced it's constraint to always evaluate to false.

The writeln() in the unittest has the copy of the constraint expression and
it does evaluate to false. If I comment out the second template, this code
will compile as DMD will match the first template.

I'm using this forced "&& false" expression because I was trying out all
sorts of type/value expressions but they never worked for me.

Anyways, I'd appreciate any help here. :)




On Wed, Jul 28, 2010 at 5:22 PM, Andrej Mitrovic <andrej.mitrovich at gmail.com
> wrote:

> These templates seem to be hard to get right. I guess with experience they
> get easier to write and comprehend. Anyways, thanks for the explanation.
>
>
> On Wed, Jul 28, 2010 at 4:44 PM, Philippe Sigaud <
> philippe.sigaud at gmail.com> wrote:
>
>> On Wed, Jul 28, 2010 at 05:50, Andrej Mitrovic <
>> andrej.mitrovich at gmail.com> wrote:
>>
>> I won't comment on the double/float issue, I do not anything about it.
>>
>>
>>> T[] find(T, E)(T[] haystack, E needle)
>>>    if (is(typeof(haystack[0] != needle) == bool))
>>>
>>> T1[] find(T1, T2)(T1[] longer, T2[] shorter)
>>>    if (is(typeof(longer[0 .. 1] == shorter) : bool))
>>>
>>> Also, Andrei, you never explained the if(is()) signature of the second
>>> templated function. I hope to get some pointers on that. :)
>>>
>>
>> I'll have a try at this one.
>> As you may know, the is(typeof()) syntax is a way to try to compile an
>> expression and see if it works. If it works, it has a type, given by typeof
>> and is(Type) returns true. So the first one is really saying: "Hey compiler,
>> may I compare an element of haystack (of type T) with an E
>> In this case, longer is an array. So longer[0] would be an element, a T1.
>> There is no chance that shorter will match as an element cannot be equal to
>> an array ... except, of course, if longer is an array of T2[]  (T1 == T2[]).
>> Longer is a T2[][]. That may happen for arrays of strings, strings being
>> arrays of chars. And I think that's the problem you have in your last unit
>> test.
>>
>> Anyway, he takes longer[0..1] to get a slice, which is a dynamic array, a
>> T1[] and hence comparable to a T2[]... most of the time.
>>
>> As for using ': bool' instead of '== bool' as in the first find(),  I
>> don't think there is any difference in this case. I understand T == U as 'T
>> is the exact same type as U', whereas T : U is for me "T is a subtype of U".
>> But then, a subtype of bool is pretty much constrained to be a bool. The T :
>> U syntax is pretty much only used for classes : if(is(T : MyClass)) is
>> saying : 'compile this only if T is a subclass of MyClass'.
>>
>>
>> Philippe
>>
>>
>>
>> , except if longer is in fact
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20100730/61eeeed5/attachment.html>


More information about the Digitalmars-d mailing list