steven@pacific.csl.uiuc.edu (Steven Parkes) (05/01/91)
Under cfront 2.0, in the following program, x does not seem to convert to an (int&) the way that we think it should. Any comments on what the correct semantics for this syntax are? Could someone run it under cfront 2.1 and tell us whether it produces an error or not ... class Int { public: Int () {} Int ( int x ) : me ( x ) {} operator int& () { return me; } int* operator & () { return &me; } private: int me; }; int f(int x ) { return x; } main() { Int x; x=10; // works x+=5; // works x = * &x; // works f(x); // this doesn't work ... f( (int&) x); // ... but this does }
rmartin@clear.com (Bob Martin) (05/02/91)
In article <1991May1.143350.19206@roundup.crhc.uiuc.edu> steven@pacific.csl.uiuc.edu writes: >Under cfront 2.0, in the following program, x does not seem to convert to >an (int&) the way that we think it should. > >class Int { > > public: > Int () {} > Int ( int x ) : me ( x ) {} > operator int& () { return me; } > int* operator & () { return &me; } > > private: > int me; >}; > >int f(int x ) { return x; } > >main() >{ > Int x; > x=10; // works > x+=5; // works > x = * &x; // works > f(x); // this doesn't work ... > f( (int&) x); // ... but this does >} It appears that the compiler is invoking the rule as stated in 12.3.2 of the ARM: "At most one user-defined conversion (Constructor or conversion function) is implicitly applied to a single value." Thus the compiler is willing to convert Int to int& but not willing to convert Int to int since that would take two implicit steps. You were after an Int class that could be used as an LValue in int expressions with the same semantics as an int. This can be created, but at a greater cost than your example. operator int() is necessary because of the rule stated in the previous paragraph. But that means that including an operator int&() will cause ambiguities. (try it!). So you must declare operator functions for all the operators you want to use. For example: class Int { public: // // note removal of operator& and conversion of operator int&() to // operator int(). Note also addition of operator+=(). // Int () {} Int ( int x ) : me ( x ) {} operator int () {return me;} operator +=(int x) {me += x; return me;} private: int me; }; int f(int x ) { return x; } main() { Int x; int i; x=10; // works due to Int(int) constructor and default =. x+=5; // works due to operator+=() x = * &x; // works due to default operator= f(x); // works due to operator int(); i=x; // works due to opeartor int(); x=x+i; // works due to operator int() and Int(int); } -- +-Robert C. Martin-----+:RRR:::CCC:M:::::M:| Nobody is responsible for | | rmartin@clear.com |:R::R:C::::M:M:M:M:| my words but me. I want | | uunet!clrcom!rmartin |:RRR::C::::M::M::M:| all the credit, and all | +----------------------+:R::R::CCC:M:::::M:| the blame. So there. |