One case of careless opDispatch :)
Robert Jacques
sandford at jhu.edu
Thu Jul 15 12:52:56 PDT 2010
On Thu, 15 Jul 2010 15:34:23 -0400, Dmitry Olshansky
<dmitry.olsh at gmail.com> wrote:
> 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.
>
:) I've run into this before, with other compile-time tests such as
isAssociativeArray. Often, the real bug is the tests themselves are too
permissive.
More information about the Digitalmars-d
mailing list