Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Conversion from scalar to class type

Reply
Thread Tools

Conversion from scalar to class type

 
 
Dhirendra Singh
Guest
Posts: n/a
 
      05-11-2006
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: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 ?

 
Reply With Quote
 
 
 
 
red floyd
Guest
Posts: n/a
 
      05-11-2006
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: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.

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

 
Reply With Quote
 
 
 
 
Marcus Kwok
Guest
Posts: n/a
 
      05-11-2006
Dhirendra Singh <(E-Mail Removed)> 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: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&).

> 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
 
Reply With Quote
 
Dhirendra Singh
Guest
Posts: n/a
 
      05-12-2006
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: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 ?

Marcus Kwok wrote:
> Dhirendra Singh <(E-Mail Removed)> 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: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&).
>
> > 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


 
Reply With Quote
 
datar
Guest
Posts: n/a
 
      05-12-2006
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: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-----
 
Reply With Quote
 
Dhirendra Singh
Guest
Posts: n/a
 
      05-13-2006
Then why a = complex(3); passed compilation without const ?

 
Reply With Quote
 
Jonathan Mcdougall
Guest
Posts: n/a
 
      05-13-2006
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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
conversion to non-scalar type error in inheritance hierarchy kmw C++ 5 10-29-2009 04:48 PM
conversion to non-scalar type requested error venu reddy C Programming 2 03-04-2007 08:16 PM
conversion from '...' to non-scalar type '...' requested tthunder@gmx.de C++ 11 06-05-2006 09:02 PM
Replace scalar in another scalar Mark Perl Misc 4 01-27-2005 02:48 PM
Shorthand for($scalar) loops and resetting pos($scalar) Clint Olsen Perl Misc 6 11-13-2003 12:50 AM



Advertisments