Conversion from scalar to class type

D

Dhirendra Singh

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::eek:perator=( 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 ?
 
R

red floyd

Dhirendra said:
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::eek:perator=( 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.
 
M

Marcus Kwok

Dhirendra Singh said:
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::eek:perator=( 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&).
 
D

Dhirendra Singh

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::eek:perator=(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 ?
 
D

datar

Dhirendra said:
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::eek:perator=(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-----
 
J

Jonathan Mcdougall

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,204
Latest member
LaverneRua

Latest Threads

Top