TDPL: Overloading template functions

Andrej Mitrovic andrej.mitrovich at gmail.com
Tue Jul 27 20:50:26 PDT 2010


There are two templated functions that overload against each other, and should pass the unittests. But there are a few problems. Here's the example code:

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))
{
    while (longer.length >= shorter.length) {
        if (longer[0 .. shorter.length] == shorter)
            break;
        longer = longer[1 .. $];
    }
    return longer;
}

unittest {
    double[] d1 = [6.0, 1.5, 2.4, 3];
    float[] d2 = [1.5, 2.4];
    assert(find(d1, d2) == d1[1 .. $]);
}

unittest {
    double[] d = [1.5, 2.4];
    assert(find(d, 1.0) == null);
    assert(find(d, 1.5) == d);
    
    string[] s = ["one", "two"];
    assert(find(s, "two") == ["two"]);
}

The first unittest will fail. There is some funky issue going around here. This small code will pass the unittest:

import std.stdio;

void main() {
}

float x = 4.0;
double y = 4.0;

unittest {
    assert(x == y);
}

But this one will not:

import std.stdio;

void main() {
}

float x = 4.2;
double y = 4.2;

unittest {
    assert(x == y);
}

Notice I've only changed the 0's to a different number. So, if I change the first unittest in the original code to this:

unittest {
    double[] d1 = [6.0, 1.0, 2.0, 3];
    float[] d2 = [1.0, 2.0];
    assert(find(d1, d2) == d1[1 .. $]);
}

It will pass. I guess this has something to do with internal representation of floats/doubles..

The second unittest from the Example code, which I'm pasting here again for convenience:

unittest {
    double[] d = [1.5, 2.4];
    assert(find(d, 1.0) == null);
    assert(find(d, 1.5) == d);
    
    string[] s = ["one", "two"];
    assert(find(s, "two") == ["two"]);
}

Gives a compiler error saying that both of the overloaded templated functions match for the call (the last assert in the unittest).

Also, Andrei, you never explained the if(is()) signature of the second templated function. I hope to get some pointers on that. :)


More information about the Digitalmars-d mailing list