digitalmars.D - [help]operator overloading with opEquals in a class
- zhang (34/34) Nov 03 2010 This code belown can be compiled with DMD 2.050. However, it throws an e...
- Benjamin Thaut (7/40) Nov 03 2010 I'm not shure if it is a bug or not, but to fix it you could add "alias
- Steven Schveighoffer (9/18) Nov 03 2010 [snip]
- Jonathan M Davis (33/95) Nov 03 2010 It has to do with function overload sets:
- =?iso-8859-2?B?VG9tZWsgU293afFza2k=?= (14/20) Nov 03 2010 It should be:
- bearophile (7/8) Nov 03 2010 It's not obligatory yet:
- Jonathan M Davis (9/10) Nov 03 2010 I think that for some reason, opEquals() returned int in D1 instead of b...
- Andrei Alexandrescu (7/10) Nov 03 2010 [snip]
- bearophile (22/26) Nov 03 2010 If you compile this program, derived from the OP one:
- dennis luehring (5/8) Nov 04 2010 can you please create an small web-page (or blog, or whatever) to save
- Bruno Medeiros (4/16) Nov 26 2010 Indeed! Is this part of the spec, or has Walter not agreed to it?
- Andrei Alexandrescu (3/21) Nov 26 2010 I think he was worried about the compiler becoming too restrictive.
- Bruno Medeiros (10/32) Nov 29 2010 Well... I don't even know how to argue against that. I mean, when would
This code belown can be compiled with DMD 2.050. However, it throws an error message: core.exception.HiddenFuncError: Hidden method called for main.AClass I'm not sure about whether it is a bug. Thanks for any help. import std.stdio; class AClass { int data; // It's wrong bool opEquals(AClass a) { writefln("running here."); return data == a.data; } // It works // bool opEquals(Object a) // { // writefln("running here."); // return data == (cast(AClass)a).data; // } } int main(string[] args) { AClass class1 = new AClass(); AClass class2 = new AClass(); if(class1 == class2) writefln("=="); else writefln("!="); return 0; } ---------- Zhang <bitworld qq.com> s
Nov 03 2010
Am 03.11.2010 13:07, schrieb zhang:This code belown can be compiled with DMD 2.050. However, it throws an error message: core.exception.HiddenFuncError: Hidden method called for main.AClass I'm not sure about whether it is a bug. Thanks for any help. import std.stdio; class AClass { int data; // It's wrong bool opEquals(AClass a) { writefln("running here."); return data == a.data; } // It works // bool opEquals(Object a) // { // writefln("running here."); // return data == (cast(AClass)a).data; // } } int main(string[] args) { AClass class1 = new AClass(); AClass class2 = new AClass(); if(class1 == class2) writefln("=="); else writefln("!="); return 0; } ---------- Zhang<bitworld qq.com> sI'm not shure if it is a bug or not, but to fix it you could add "alias object.opEquals opEquals;" before your first opEquals. Had that already many times, it also happens a lot with opCmp. -- Kind Regards Benjamin Thaut
Nov 03 2010
On Wed, 03 Nov 2010 13:57:09 -0400, Benjamin Thaut <code benjamin-thaut.de> wrote:Am 03.11.2010 13:07, schrieb zhang:[snip]This code belown can be compiled with DMD 2.050. However, it throws an error message: core.exception.HiddenFuncError: Hidden method called for main.AClass I'm not sure about whether it is a bug. Thanks for any help.I'm not shure if it is a bug or not, but to fix it you could add "alias object.opEquals opEquals;" before your first opEquals. Had that already many times, it also happens a lot with opCmp.First, it's not a bug, you should only ever override with bool opEquals(Object). Second, using the alias trick does not work for opEquals. x == y *specifically* calls (cast(Object)x).opEquals(cast(Object)y). So if you did that, your override would never be called. -Steve
Nov 03 2010
On Wednesday, November 03, 2010 10:57:09 Benjamin Thaut wrote:Am 03.11.2010 13:07, schrieb zhang:It has to do with function overload sets: http://www.digitalmars.com/d/2.0/function.html Functions in base classes are completely shadowed by those in the derived class as far as overloading goes. Using the alias brings the overload into the overload set for the derived class. However, I would advise against declaring a version of opEquals() or opCmp() that takes anything other than an Object. The way they both work is designed around there being the one overload with takes Object, and generally speaking having function overloads which take a base and derived class is asking for trouble. As soon as you add another derived class on top of it, it's going to choke because it can no longer get an exact match. e.g. void func(A a) {...} void func(B b) {...} class A { ... } class B : A { ... } class C : B { ... } You can't call func with an object of type C without a cast because both the A and B version accept it and neither match C exactly. D's overloading rules are stricter than C++'s, which makes it so that you have a lot fewer cases (possibly none) of a particular overload being called when you expect a different one to be called, but it also makes it so that the compiler doesn't do some of the implicit conversions that you might expect it to. Really, you should just define the one opEquals() and opCmp() and cast the Object inside of it.h If you'll notice, opEquals() already isn't the function that gets called when == or != is used, but rather Objects opEquals() which takes two parameters is, so it already takes care of any issues with the two objects being the same or being null, as well as dealing with transivity and whatnot. opCmp() doesn't do that though, so you could likely still get null values in it. In any case, the design is that you directly override the opEquals() and opCmp() in Object, not that you create ones with new signatures. - Jonathan M Davis - Jonathan M DavisThis code belown can be compiled with DMD 2.050. However, it throws an error message: core.exception.HiddenFuncError: Hidden method called for main.AClass I'm not sure about whether it is a bug. Thanks for any help. import std.stdio; class AClass { int data; // It's wrong bool opEquals(AClass a) { writefln("running here."); return data == a.data; } // It works // bool opEquals(Object a) // { // writefln("running here."); // return data == (cast(AClass)a).data; // } } int main(string[] args) { AClass class1 = new AClass(); AClass class2 = new AClass(); if(class1 == class2) writefln("=="); else writefln("!="); return 0; } ---------- Zhang<bitworld qq.com> sI'm not shure if it is a bug or not, but to fix it you could add "alias object.opEquals opEquals;" before your first opEquals. Had that already many times, it also happens a lot with opCmp.
Nov 03 2010
Dnia 03-11-2010 o 13:07:25 zhang <bitworld qq.com> napisa=B3(a):// It works // bool opEquals(Object a) // { // writefln("running here."); // return data =3D=3D (cast(AClass)a).data; // }It should be: override equals_t opEquals(Object o) { writefln("running here."); if (auto a =3D cast(AClass) o) return data =3D=3D a.data; else return false; } I'm surprised it even compiled without 'override'. BTW, anybody knows what the equals_t bool alias is for? -- = Tomek
Nov 03 2010
Tomek S:I'm surprised it even compiled without 'override'.It's not obligatory yet: http://d.puremagic.com/issues/show_bug.cgi?id=3836 It's one of the warnings I am waiting to become errors: http://d.puremagic.com/issues/show_bug.cgi?id=4216 Bye, bearophile
Nov 03 2010
On Wednesday, November 03, 2010 13:27:16 Tomek Sowi=F1ski wrote:BTW, anybody knows what the equals_t bool alias is for?I think that for some reason, opEquals() returned int in D1 instead of bool= , but=20 not having used D1, I'm 100% not sure. If that's the case, then using equal= s_t=20 and having equals_t be int in D1 and bool in D2 makes the code more portabl= e=20 between the two versions. Personally, I always just use bool though. =2D Jonathan M Davis
Nov 03 2010
On 11/3/10 7:07 AM, zhang wrote:This code belown can be compiled with DMD 2.050. However, it throws an error message: core.exception.HiddenFuncError: Hidden method called for main.AClass I'm not sure about whether it is a bug. Thanks for any help.[snip] That hidden functions are signaled during run time and not compile time is a misunderstanding between design and implementation. There should not be a HiddenFunc exception and the compiler should just refuse to compile the program. Andrei
Nov 03 2010
Andrei:That hidden functions are signaled during run time and not compile time is a misunderstanding between design and implementation. There should not be a HiddenFunc exception and the compiler should just refuse to compile the program.If you compile this program, derived from the OP one: import std.c.stdio: puts; class Foo { int x; bool opEquals(Foo other) { // wrong puts("running here."); return this.x == other.x; } } void main() { auto f1 = new Foo(); auto f2 = new Foo(); puts((f1 == f2) ? "==" : "!="); } With -w, it doesn't compile and gives the error: test.d(3): Error: class test.Foo object.Object.opEquals(Object o) is hidden by Foo That warning just needs to become an error message as soon as possible. See: http://d.puremagic.com/issues/show_bug.cgi?id=4216 It's in my list of about 20 very small changes that I'd like to see ASAP in D2. Bye, bearophile
Nov 03 2010
That warning just needs to become an error message as soon as possible. See: http://d.puremagic.com/issues/show_bug.cgi?id=4216 It's in my list of about 20 very small changes that I'd like to see ASAP in D2.can you please create an small web-page (or blog, or whatever) to save your always (very most of the time) ideas, change request etc. maybe splitted by D2,D3 - small, huge, evil ratings... and keep that up to date - so can refere better and nothing is lost in the huge mass of others posts in this newsgroup
Nov 04 2010
On 03/11/2010 20:33, Andrei Alexandrescu wrote:On 11/3/10 7:07 AM, zhang wrote:Indeed! Is this part of the spec, or has Walter not agreed to it? -- Bruno Medeiros - Software EngineerThis code belown can be compiled with DMD 2.050. However, it throws an error message: core.exception.HiddenFuncError: Hidden method called for main.AClass I'm not sure about whether it is a bug. Thanks for any help.[snip] That hidden functions are signaled during run time and not compile time is a misunderstanding between design and implementation. There should not be a HiddenFunc exception and the compiler should just refuse to compile the program. Andrei
Nov 26 2010
On 11/26/10 9:30 AM, Bruno Medeiros wrote:On 03/11/2010 20:33, Andrei Alexandrescu wrote:I think he was worried about the compiler becoming too restrictive. AndreiOn 11/3/10 7:07 AM, zhang wrote:Indeed! Is this part of the spec, or has Walter not agreed to it?This code belown can be compiled with DMD 2.050. However, it throws an error message: core.exception.HiddenFuncError: Hidden method called for main.AClass I'm not sure about whether it is a bug. Thanks for any help.[snip] That hidden functions are signaled during run time and not compile time is a misunderstanding between design and implementation. There should not be a HiddenFunc exception and the compiler should just refuse to compile the program. Andrei
Nov 26 2010
On 26/11/2010 16:56, Andrei Alexandrescu wrote:On 11/26/10 9:30 AM, Bruno Medeiros wrote:Well... I don't even know how to argue against that. I mean, when would a programmer ever prefer a runtime error instead of a compile-time one in this scenario? It's akin to saying the override keyword should never create a compile-time error, but instead throw a runtime one if the override-marked method doesn't actually override a super method. (note: I know it's not your reasoning, but Walter's) -- Bruno Medeiros - Software EngineerOn 03/11/2010 20:33, Andrei Alexandrescu wrote:I think he was worried about the compiler becoming too restrictive. AndreiOn 11/3/10 7:07 AM, zhang wrote:Indeed! Is this part of the spec, or has Walter not agreed to it?This code belown can be compiled with DMD 2.050. However, it throws an error message: core.exception.HiddenFuncError: Hidden method called for main.AClass I'm not sure about whether it is a bug. Thanks for any help.[snip] That hidden functions are signaled during run time and not compile time is a misunderstanding between design and implementation. There should not be a HiddenFunc exception and the compiler should just refuse to compile the program. Andrei
Nov 29 2010