Ali Çehreli wrote: > I have experience with C++ and still don't understand why opCall exists. > :) I think I heard that opCall was needed to create struct objects > before structs had constructors in D. > > Now structs do have constructors, which sometimes conflict with opCall. :)
I also have some C++ experience, but it seems to be confusing as much as complementary with respect to D ... :-) Current source of confusion relates to declaring objects of a class whose constructor takes input -- confusion because I can write, class Foo { int x; uint y; this() { x = -1; y = 2; } } void main() { Foo f; } and have no problem, but if instead the constructor is, this(int z) { x = z; y = 2; } ... it seems like I have to write instead, auto f = new Foo(-1); ... and if I write as per C++, Foo f(-1); ... I get back a compiler error: "found 'f' when expecting ';' following 'statement'". Am I right in thinking that the 'new' syntax is necessary when the class has a constructor which takes input? This creates confusion also because in C++ one associates 'new' with dynamic allocation of memory, and it requires a consequent 'delete' statement. I know that D has GC, and I know that it also has 'delete' statements, but ... this one is 'ouch' for me :-P In my own code (cleaned up, attached following this email, and now working), I note the line, auto aw = new AvgWeighted(ratings,reputationUser,reputationObject); where if I write instead, AvgWeighted aw(ratings,reputationUser,reputationObject); ... I get the error: Error: ratings is used as a type Error: cannot have parameter of type void Error: reputationUser is used as a type Error: cannot have parameter of type void Error: reputationObject is used as a type Error: cannot have parameter of type void ... which is difficult to understand, but I presume it relates to the fact that an array is a class and not a value. Apologies if these are relatively trivial questions -- I am sure they will all become clearer once Andrei Alexandrescu's book is out ... :-) Thanks & best wishes, -- Joe ///////// My code .... struct Rating { uint u; // user ID uint o; // object ID double r; // rating value } class Reputation { this() {} this(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) {} } class AvgWeighted : Reputation { double[] weightSum; this(){} this(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) { opCall(ratings,reputationUser,reputationObject); } void opCall(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) { weightSum.length = reputationObject.length; weightSum[] = 0; reputationObject[] = 0; foreach(ref Rating r; ratings) { reputationObject[r.o] += reputationUser[r.u]*r.r; weightSum[r.o] += reputationUser[r.u]; } foreach(uint o, ref double r; reputationObject) r /= weightSum[o]; } } class AvgArithmetic : AvgWeighted { this(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) { opCall(ratings,reputationUser,reputationObject); } void opCall(ref Rating[] ratings, ref double[] reputationUser, ref double[] reputationObject) { reputationUser[] = 1; super.opCall(ratings,reputationUser,reputationObject); } } void main() { Rating[] ratings; double[] reputationUser; double[] reputationObject; foreach(uint u; 0..999) reputationUser ~= 0.1*(u%3); reputationObject.length = 1; reputationObject[] = 0; foreach(uint u;0..reputationUser.length) { Rating _r = {u,0,(u%3)}; writefln("%u %g",_r.u,_r.r); ratings ~= _r; } auto aw = new AvgWeighted(ratings,reputationUser,reputationObject); aw(ratings,reputationUser,reputationObject); foreach(double o; reputationObject) writefln("%g",o); }