Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Conversion from scalar to class type (http://www.velocityreviews.com/forums/t453971-conversion-from-scalar-to-class-type.html)

Dhirendra Singh 05-11-2006 08:11 PM

Conversion from scalar to class type
 
Hi,
The following C++ program is not compiling on my system.

#include <iostream>
using namespace std;

class complex {
double re, im;
public:
complex( ) :re(0), im(0) {}
complex( double r ) :re(r), im(0) {}
complex( double r, double i) :re(r), im(i) {}
complex& operator=( complex& );
};

complex& complex::operator=( complex& b )
{
re = b.re;
im = b.im;
return *this;
}

int main()
{
complex a ;
a = 3; // Gives compilation error. Not able to convert from scalar
3 to complex(3).
a = complex(3); // this is perfectly ok.
return 0;
}

I am using visual C++ compiler.
I am not able to figure out if there is something wrong with the
concept or compiler is stupid ?


red floyd 05-11-2006 08:20 PM

Re: Conversion from scalar to class type
 
Dhirendra Singh wrote:
> Hi,
> The following C++ program is not compiling on my system.
>
> #include <iostream>
> using namespace std;
>
> class complex {
> double re, im;
> public:
> complex( ) :re(0), im(0) {}
> complex( double r ) :re(r), im(0) {}
> complex( double r, double i) :re(r), im(i) {}
> complex& operator=( complex& );
> };
>
> complex& complex::operator=( complex& b )
> {
> re = b.re;
> im = b.im;
> return *this;
> }
>
> int main()
> {
> complex a ;
> a = 3; // Gives compilation error. Not able to convert from scalar
> 3 to complex(3).


requires 2 conversions: integer => double. double => complex.
a = 3.; // should compile.

> a = complex(3); // this is perfectly ok.
> return 0;
> }
>
>


Marcus Kwok 05-11-2006 08:29 PM

Re: Conversion from scalar to class type
 
Dhirendra Singh <dhirendraks@gmail.com> wrote:
> Hi,
> The following C++ program is not compiling on my system.
>
> #include <iostream>
> using namespace std;
>
> class complex {


It may not affect you here since you do not #include <complex>, but
beware of the possibility of the combination of your own class called
"complex" combined with the "using namespace std;".

> double re, im;
> public:
> complex( ) :re(0), im(0) {}
> complex( double r ) :re(r), im(0) {}
> complex( double r, double i) :re(r), im(i) {}
> complex& operator=( complex& );
> };
>
> complex& complex::operator=( complex& b )
> {
> re = b.re;
> im = b.im;
> return *this;
> }
>
> int main()
> {
> complex a ;
> a = 3; // Gives compilation error. Not able to convert from scalar
> 3 to complex(3).


Right, you have no operator=() that takes an int. You have a
constructor that takes a double, but your assignment you have would
require a conversion from int to double, then from double to complex
(via the constructor). Since it requires two conversions, the compiler
complains. However, if you do

complex a = 3; // initialization, not assignment

then this only requires one conversion, and works.

> a = complex(3); // this is perfectly ok.


Right. Looking back though, your operator=(complex&) should probably be
operator=(const complex&).

> return 0;
> }
>
> I am using visual C++ compiler.
> I am not able to figure out if there is something wrong with the
> concept or compiler is stupid ?


--
Marcus Kwok
Replace 'invalid' with 'net' to reply

Dhirendra Singh 05-12-2006 11:27 AM

Re: Conversion from scalar to class type
 
Hi,
Problem do not seems to be with the double conversion.
even a = 3.0; do not succeed.

As you pointed out problem is with the operator= definition.
if i change the definition to complex& operator=( const complex& )
it compiles and execute perfectly.

error message generated by the Visual C++ compiler is misleading. it
gives the error...
"error C2679: binary '=' : no operator found which takes a right-hand
operand of type 'int' (or there is no acceptable conversion)"

It seems solaris compiler is better than Visual C++ compiler. it gives
the exact error message.
Error: Cannot assign int to complex without "complex::operator=(const
complex&)";.

but why it is necessary to define the operator argument as const
reference ?
what is the problem if i pass it as reference only ?

Marcus Kwok wrote:
> Dhirendra Singh <dhirendraks@gmail.com> wrote:
> > Hi,
> > The following C++ program is not compiling on my system.
> >
> > #include <iostream>
> > using namespace std;
> >
> > class complex {

>
> It may not affect you here since you do not #include <complex>, but
> beware of the possibility of the combination of your own class called
> "complex" combined with the "using namespace std;".
>
> > double re, im;
> > public:
> > complex( ) :re(0), im(0) {}
> > complex( double r ) :re(r), im(0) {}
> > complex( double r, double i) :re(r), im(i) {}
> > complex& operator=( complex& );
> > };
> >
> > complex& complex::operator=( complex& b )
> > {
> > re = b.re;
> > im = b.im;
> > return *this;
> > }
> >
> > int main()
> > {
> > complex a ;
> > a = 3; // Gives compilation error. Not able to convert from scalar
> > 3 to complex(3).

>
> Right, you have no operator=() that takes an int. You have a
> constructor that takes a double, but your assignment you have would
> require a conversion from int to double, then from double to complex
> (via the constructor). Since it requires two conversions, the compiler
> complains. However, if you do
>
> complex a = 3; // initialization, not assignment
>
> then this only requires one conversion, and works.
>
> > a = complex(3); // this is perfectly ok.

>
> Right. Looking back though, your operator=(complex&) should probably be
> operator=(const complex&).
>
> > return 0;
> > }
> >
> > I am using visual C++ compiler.
> > I am not able to figure out if there is something wrong with the
> > concept or compiler is stupid ?

>
> --
> Marcus Kwok
> Replace 'invalid' with 'net' to reply



datar 05-12-2006 12:11 PM

Re: Conversion from scalar to class type
 
Dhirendra Singh wrote:
> Hi,
> Problem do not seems to be with the double conversion.
> even a = 3.0; do not succeed.
>
> As you pointed out problem is with the operator= definition.
> if i change the definition to complex& operator=( const complex& )
> it compiles and execute perfectly.
>
> error message generated by the Visual C++ compiler is misleading. it
> gives the error...
> "error C2679: binary '=' : no operator found which takes a right-hand
> operand of type 'int' (or there is no acceptable conversion)"
>
> It seems solaris compiler is better than Visual C++ compiler. it gives
> the exact error message.
> Error: Cannot assign int to complex without "complex::operator=(const
> complex&)";.


>
> but why it is necessary to define the operator argument as const
> reference ?
> what is the problem if i pass it as reference only ?


Yeah. Compiler ties to do conversion from int to complex. At first it
takes int and converts it to double. Then it make a temporary complex
using 'complex( double r );'. And then it wants to past that temporary
complex to 'complex& operator=( complex& )' to make the assignment. But
temporary objects are always const. Function 'complex& operator=(
complex& )' does not 'promise' to not change the argument so compiler
will not allow this. If it were 'complex& operator=( const complex& )'
then you couldn't change the argument inside the function so passing a
const argument would be possible.

Greetings
--
Tao that can be named is not the Tao.
----BEGIN GEEK CODE BLOCK----
v: 3.12
GIT dpu s+:--- a C+++>++++$ UL+++>++++ P+ L++>++++ E->+ W+ N++ o? K?
w(---) O? M? V? PS+ PE+ Y+ PGP+ t+ 5? X R+ tv- b++(++++) DI(+) D- G e h*
r-- y+
-----END GEEK CODE BLOCK-----

Dhirendra Singh 05-13-2006 08:45 AM

Re: Conversion from scalar to class type
 
Then why a = complex(3); passed compilation without const ?


Jonathan Mcdougall 05-13-2006 09:14 AM

Re: Conversion from scalar to class type
 
datar wrote:
> Dhirendra Singh wrote:
> > Hi,
> > Problem do not seems to be with the double conversion.
> > even a = 3.0; do not succeed.


To the OP:

This is because a temporary complex object (an rvalue) is created from
3.0, but your assignment operator takes a non-const reference. Make it

complex& operator=(const complex& c);

> Yeah. Compiler ties to do conversion from int to complex. At first it
> takes int and converts it to double. Then it make a temporary complex
> using 'complex( double r );'.


This is correct. Several people pointed out the "two conversions" rule,
forgetting that it only applies to user defined conversions (so
int->double->complex is ok).

> And then it wants to past that temporary
> complex to 'complex& operator=( complex& )' to make the assignment. But
> temporary objects are always const.


That's wrong.

struct C
{
void f();
};

int main()
{
C().f();
}


Jonathan



All times are GMT. The time now is 10:26 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.