As a practical habit, once I stumble upon a very tricky error, I usually share the valuable knowledge of "when you do this ... and get that ... it's probably because ... "
Damn, sometimes they can even become cool quizzes...
So to warn those oblivious to the dangers of opDispatch, here is my the yesterday nightmare, the striped down code below.

import std.algorithm;
import std.array;

class Widget {
    string _name;
    Widget[] _children;
    this(in string name){
        _name = name.idup;
    }
    Widget opDispatch(string nm)(){
        auto r = find!((Widget c){ return c._name == nm; })(_children);
        return r.front();
    }
}

void main(){
    Widget g = new Widget("G");
    Widget warr[] = [new Widget("W"),g];
    find(warr,g);
}

produces:

Error 1 Error: template std.algorithm.startsWith(alias pred = "a == b",Range,Ranges...) if (isInputRange!(Range) && Ranges.length > 0 && is(typeof(binaryFun!(pred)(doesThisStart.front,withOneOfThese[0].front)))) startsWith(alias pred = "a == b",Range,Ranges...) if (isInputRange!(Range) && Ranges.length > 0 && is(typeof(binaryFun!(pred)(doesThisStart.front,withOneOfThese[0].front)))) matches more than one template declaration, C:\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(1892):startsWith(alias pred = "a == b",Range,Ranges...) if (isInputRange!(Range) && Ranges.length > 0 && is(typeof(binaryFun!(pred)(doesThisStart.front,withOneOfThese[0].front)))) and C:\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d(1980):startsWith(alias pred = "a == b",Range,Elements...) if (isInputRange!(Range) && Elements.length > 0 && is(typeof(binaryFun!(pred)(doesThisStart.front,withOneOfThese[0])))) C:\dmd2\windows\bin\..\..\src\phobos\std\algorithm.d 1488

The tricky part is that *any* class with unconstrained (or loosely constrained) opDispatch is also a Range, and at least a bidirectional one, since it "provides" all the primitives: front, popFront etc. In fact such classes could penetrate almost any attempts at C++ trait-like stuff and should be avoided.

The moral: unconstrainted opDispatch == TROUBLE.
Hope that helps!

P.S. Strangely enough, that problem haven't showed up until update to 2.047 release, so it's probably detonated by some changes to Phobos. I guess better sooner than later.

--
Dmitry Olshansky

Reply via email to