jima@hplsla.HP.COM (Jim Adcock) (10/05/89)
// g++ 1.35.x accepts the following, AT&T 2.0 rejects it. Which is "right"? // What are the general coercion/overloading rules for x =op y verses // x = x op y? [this seems to be another version of lvalue issues] extern "C" {int printf(const char* const p, ...);}; class Int { private: int i; public: Int(int I=0):i(I){} operator int(){return i;} }; void main() { Int I=10; printf("%d\n",(int)I); I = I * I; // okay by both g++ 1.35.x and AT&T 2.0 printf("%d\n",(int)I); I *= I; // g++ 1.35.x accepts, 2.0 calls it an error printf("%d\n",(int)I); }
shankar@hpclscu.HP.COM (Shankar Unni) (10/06/89)
> I = I * I; // okay by both g++ 1.35.x and AT&T 2.0 > I *= I; // g++ 1.35.x accepts, 2.0 calls it an error I think the key here is that in the first case, you are assigning to I a value with an implicit constructor (Int(int)). In the second case, you are either applying a "*=" operator to an Int (no such operator defined), or to an int (which is generated by a function call, which is not an lvalue). I don't know what to say here - "gcc" seems to "Do What I Mean, Not What I Say", which is nice and friendly, but I don't think this is legal.. Just one of those gotcha's (sigh!) ---- Shankar.
jima@hplsla.HP.COM (Jim Adcock) (10/10/89)
>In the second case, you are either applying a "*=" operator to an Int (no >such operator defined), or to an int (which is generated by a function >call, which is not an lvalue). In which case, seems to me that coercion oerators should be considered to return a reference, so as to be legal in lvalue situations. Otherwise you can't use coercion operators for true polymorphism. Where is it defined whether coercion operators return values or lvalues? Is there anyway to declare which you'd like?
dog@cbnewsl.ATT.COM (edward.n.schiebel) (10/11/89)
From article <6590286@hplsla.HP.COM>, by jima@hplsla.HP.COM (Jim Adcock): >>In the second case, you are either applying a "*=" operator to an Int (no >>such operator defined), or to an int (which is generated by a function >>call, which is not an lvalue). > > In which case, seems to me that coercion oerators should be considered to > return a reference, so as to be legal in lvalue situations. Otherwise > you can't use coercion operators for true polymorphism. Where is it defined > whether coercion operators return values or lvalues? Is there anyway to > declare which you'd like? You get to declare the coercion operators, so you decide. In general, the operators might not return a reference since the result may be computed. Also, you may not want to allow the coercion operator to return a reference to private data anyway as this violates data hiding principles. Ed Schiebel AT&T Bell Laboratories dog@vilya.att.com
jima@hplsla.HP.COM (Jim Adcock) (10/12/89)
// okay, okay -- the following "works" -- I don't know *why* I couldn't figure // out how to do this earlier. Unfortunately, now you can't explictely // coerce to (int), as may be "required" to send Int to a "C" routine like // printf. Instead you have to coerce to (int&) -- So now users have to // remember if a class defines an (int) coercion or and (int&) coercion. // [Its not practical to have both, since that results in mega-ambiguities] // -- And no, I'm not really writing an "Int" class. "Int" is just a // metaphor for writing C++ classes supporting "as-if" polymorphism. For // example, one might want to write an "IntStack" where the top-of-stack can // be used "as-if" it were an int. extern "C" {int printf(const char* const p, ...);}; class Int { private: int i; public: Int(int I=0):i(I){} operator int&(){return i;} }; void main() { Int I=10; printf("%d\n",(int&)I); I = I * I; // okay by both g++ 1.5.x and AT&T 2.0 printf("%d\n",(int&)I); I *= I; // g++ 1.35.x accepts, 2.0 accepts it too printf("%d\n",(int&)I); }