On Thursday, April 19, 2012 00:49:29 Namespace wrote: > Too early happy, now it seems opEquals wouldn't be called... > I tried this again: > > U opCast(U)() const if (is(Unqual!U == Vector2D!byte) || > is(Unqual!U == Vector2D!ubyte) || > is(Unqual!U == Vector2D!short) || > is(Unqual!U == Vector2D!ushort) || > is(Unqual!U == Vector2D!int) || > is(Unqual!U == Vector2D!uint) || > is(Unqual!U == Vector2D!long) || > is(Unqual!U == Vector2D!ulong) || > is(Unqual!U == Vector2D!float) || > is(Unqual!U == Vector2D!double) || > is(Unqual!U == Vector2D!real)) > { > return U(this.x, this.y); > } > > And normal casts works perfectly but what should i do if i get > Object like in opEquals? > I think you want me to say what I understand now slowly: it does > not work with Object. Isn't it? > It's a very unhappy solution to call > > if (vs == Vector2s(vf)) as simply if (vs == vf) > > If there any other solutions or any ideas to fix my solution in > my previous post?
It looks like you're dealing with an opCast bug - either http://d.puremagic.com/issues/show_bug.cgi?id=5747 or a variant of it. If you declare another overload of opCast: Object opCast(T)() const if(is(Unqual!T == Object)) { return this; } then it should work. I would also point out that it's really bizarre that you're using classes here. You definitely seem to be trying to treat them as value types and don't need polymorphism at all. So, I'd really advise using structs. However, if you did, then you definitely would have to use explict casts with opEquals, because it would require the exact type rather than Object. So, if you're insistent on not needing to cast, then structs aren't going to do what you want. But given that you're dealing with vectors of floats and ints which aren't implicitly convertible (or at least, float isn't implicitly convertible to int), it would make perfect sense to expect to have to cast them to compare them or have them do anything with each other, since that's what happens with the built-in types. Also, there's no need to check for null in opEquals. == actually gets translated to this: bool opEquals(Object lhs, Object rhs) { // If aliased to the same object or both null => equal if (lhs is rhs) return true; // If either is null => non-equal if (lhs is null || rhs is null) return false; // If same exact type => one call to method opEquals if (typeid(lhs) is typeid(rhs) || typeid(lhs).opEquals(typeid(rhs))) return lhs.opEquals(rhs); // General case => symmetric calls to method opEquals return lhs.opEquals(rhs) && rhs.opEquals(lhs); } So, the issues of whether you're comparing an object against itself or where the object is null are taken care of for you. It also makes opEquals more correct by enforcing that it's equal in both directions when the types aren't the same. - Jonathan M Davis