[comp.lang.c++] implicit conversion to a reference

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.     |