Conversion from scalar to class type

Discussion in 'C++' started by Dhirendra Singh, May 11, 2006.

  1. 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 ?
     
    Dhirendra Singh, May 11, 2006
    #1
    1. Advertising

  2. Dhirendra Singh

    red floyd Guest

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

    > a = complex(3); // this is perfectly ok.
    > return 0;
    > }
    >
    >
     
    red floyd, May 11, 2006
    #2
    1. Advertising

  3. Dhirendra Singh

    Marcus Kwok Guest

    Dhirendra Singh <> 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::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&).

    > 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
     
    Marcus Kwok, May 11, 2006
    #3
  4. 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 ?

    Marcus Kwok wrote:
    > Dhirendra Singh <> 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::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&).
    >
    > > 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, May 12, 2006
    #4
  5. Dhirendra Singh

    datar Guest

    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::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-----
     
    datar, May 12, 2006
    #5
  6. Then why a = complex(3); passed compilation without const ?
     
    Dhirendra Singh, May 13, 2006
    #6
  7. 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
     
    Jonathan Mcdougall, May 13, 2006
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. venu reddy

    conversion to non-scalar type requested error

    venu reddy, Feb 19, 2007, in forum: C Programming
    Replies:
    2
    Views:
    16,950
    Barry Schwarz
    Mar 4, 2007
  2. Replies:
    11
    Views:
    11,320
  3. kmw
    Replies:
    5
    Views:
    1,880
    James Kanze
    Oct 29, 2009
  4. Clint Olsen
    Replies:
    6
    Views:
    376
    Jeff 'japhy' Pinyan
    Nov 13, 2003
  5. Mark

    Replace scalar in another scalar

    Mark, Jan 27, 2005, in forum: Perl Misc
    Replies:
    4
    Views:
    171
    Arndt Jonasson
    Jan 27, 2005
Loading...

Share This Page