Overloading the "=" operator for Complex numbers

P

Pmb

I've been working on creating a Complex class for my own learning purpose
(learn through doing etc.). I'm once again puzzled about something. I can't
figure out how to overload the assignment operator.

Here's what I'm trying to do. I've defined class Complex as

class Complex {
friend ostream &operator<<( ostream &, Complex & );
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );
Complex operator=( Complex & );
Complex conjugate();
float magnitude();
private:
float re;
float im;
};

The constructor is

Complex::Complex( float a, float b )
: re( a ), im( b ) { }

I have no idea how to write the overload function though. This doesn't work

Complex Complex::eek:perator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}


Help!!!! :)

Thanks in advance!

Pmb
 
A

Alf P. Steinbach

* "Pmb said:
I have no idea how to write the overload function though. This doesn't work

Complex Complex::eek:perator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}


Help!!!! :)

Should the "=" operation ever _change_ the value that is on the right
hand side of '='?

No?

In that case, it should be 'const'.

Should you ever be able to write e.g.


a = b = Complex( 1, 2 );

?

Yes?

In that case, the return value should be a reference so that it can
be modified (e.g., in turn invoking '=' on the result).
 
P

Pmb

Alf P. Steinbach said:
Should the "=" operation ever _change_ the value that is on the right
hand side of '='?

No?

In that case, it should be 'const'.

I'm not interested in worrying about const and program integrity at this
point. This code will never be used. This particular program is simply for
me to learn about writing overload functions for operators.

Should you ever be able to write e.g.


a = b = Complex( 1, 2 );

?

Yes?

In that case, the return value should be a reference so that it can
be modified (e.g., in turn invoking '=' on the result).

Do you mean something like

Complex &operator=( Complex & );

Complex &Complex::eek:perator=( Complex &z )
{
<??>
return this;
}

I still don't see what to place in the body to do the work. Suppose

class Complex {
friend ostream &operator<<( ostream &, Complex & );
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );
Complex &operator=( Complex & );
Complex conjugate();
float magnitude();
private:
float re;
float im;
};

It would seem to me that the operator function would be

Complex &Complex::eek:perator=( Complex &z )
{
re = z.re;
im = z.im;

return this;
}

But this doesn't work.

Pmb
 
A

Alf P. Steinbach

* "Pmb said:
I'm not interested in worrying about const and program integrity at this
point. This code will never be used. This particular program is simply for
me to learn about writing overload functions for operators.

You will not learn about overloading in C++ if you refuse to consider
'const'.


Do you mean something like

Complex &operator=( Complex & );

Complex &Complex::eek:perator=( Complex &z )
{
<??>
return this;
}

I still don't see what to place in the body to do the work. Suppose

class Complex {
friend ostream &operator<<( ostream &, Complex & );
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );
Complex &operator=( Complex & );
Complex conjugate();
float magnitude();
private:
float re;
float im;
};

It would seem to me that the operator function would be

Complex &Complex::eek:perator=( Complex &z )
{
re = z.re;
im = z.im;

return this;
}

But this doesn't work.

Say rather, it does not _compile_.

First make it compile.
 
R

Rob Williscroft

Pmb wrote in in comp.lang.c++:
I've been working on creating a Complex class for my own learning
purpose (learn through doing etc.). I'm once again puzzled about
something. I can't figure out how to overload the assignment operator.

You're not overloading anything here, you're *declaring* and
then *defining* Complex::eek:perator = ( Complex & );
Here's what I'm trying to do. I've defined class Complex as

#include said:
class Complex {
friend ostream &operator<<( ostream &, Complex & );

friend std::eek:stream &operator<<( std::eek:stream &, Complex & );

When I compiled your code the above was the only error I found.
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );

All of the above *create* a new value, so its appropriate that
they return by value.
Complex operator=( Complex & );

The above dose *not* create a new value, but modifies the
'this' object, logicaly it should return Complex &.

Also it doesn't modify is argument, so you should prefer
Complex const &. As well as being "const correct" this will
allow you to later write code like:

Complex a( 1, 2 ), b( 2, 3 );

a = b.conjugate();

or:

a = a + b;

As the tempraries returned by + and .conjugate() can't be passed
to a function that takes a non-const reference.
Complex conjugate();
float magnitude();
private:
float re;
float im;
};

The constructor is

Complex::Complex( float a, float b )
: re( a ), im( b ) { }

I have no idea how to write the overload function though. This doesn't
work

Complex Complex::eek:perator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}

What doesn't work about it, with the 'ostream' issue above
fixed it compiles fine for me. Are you sure the error your
seeing isn't coming from elswhere ?


Rob.
 
J

John Harrison

You will not learn about overloading in C++ if you refuse to consider
'const'.

It's worse than that. With certain compilers you will learn illegal C++. If
you then switch to a compiler that enforces const correctness you will have
to relearn C++ that you thought you already knew.

Pmb, its not so hard

Complex operator+( const Complex & ) const;
Complex& operator=( const Complex & );

john
 
P

Pmb

John Harrison said:
It's worse than that. With certain compilers you will learn illegal C++. If
you then switch to a compiler that enforces const correctness you will have
to relearn C++ that you thought you already knew.

I think you both read something into what I said that wasn't there. I said
*at this point*. When I learn a new language and try examples I make them as
simple as possible and work my way up. After I got this to compile and got
the logic correct, I was going to go back and place in the const.'s.
Pmb, its not so hard

Complex operator+( const Complex & ) const;
Complex& operator=( const Complex & );

Still doesn't work. However I'm not sure where the error is.

thanks

Pmb
 
P

Pmb

Rob Williscroft said:
What doesn't work about it, with the 'ostream' issue above
fixed it compiles fine for me. Are you sure the error your
seeing isn't coming from elswhere ?

There wasn't an "ostream" issue. I simply didn't post the entire code. I
suppose I should have in retrospect. The following is the compile error I
get from the program below

-----------------
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
d:\temp\test\example.cpp:
Error E2285 d:\temp\test\example.cpp 130: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 138: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 139: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 140: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 141: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 148: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
*** 6 errors in Compile ***

Tool completed with exit code 1
------------------

Line 130 is " uConj = u.conjugate();"
Lines 138-141 are

138 "sum = u + v;"
139 "diff = u - v;"
140 "prod = u*v;"
141 "ratio = u/v;"


What am I doing wrong this time?

Thanks

Pmb



_____________________________________________
#include <iostream.h>
#include <math.h>

class Complex {
friend ostream &operator<<( ostream &, Complex & );
public:
Complex( float = 0.0, float = 0.0 );
Complex operator+( Complex & );
Complex operator-( Complex & );
Complex operator*( Complex & );
Complex operator/( Complex & );
Complex operator=( Complex & );
private:
float re;
float im;
};

ostream &operator<<( ostream &output, Complex &z )
{
float x = z.re, y = z.im;

if ( y == 0 ) // z = a
output << x;
else if ( x == 0 && y > 0 ) // z = i b
output << "i " << y;
else if ( x == 0 && y < 0 ) // z = - i b
output << "- i " << -y;
else if ( x > 0 && y > 0 ) // z = a + i b
output << x << " + i " << z.im;
else if ( x > 0 && y < 0 ) // z = a - i b
output << x << " - i " << -y;
else if ( x < 0 && y < 0 ) // z = -a - i b
output << x << " - i " << -y;
else if ( x < 0 && y > 0 ) // z = -a + i b
output << x << " + i " << y;

return output;
}

Complex::Complex( float a, float b )
: re( a ), im( b) { }

Complex Complex::eek:perator+( Complex &z )
{
return Complex( re + z.re, im + z.im );
}

Complex Complex::eek:perator-( Complex &z )
{
return Complex( re - z.re, im - z.im );
}

Complex Complex::eek:perator*( Complex &z )
{
// z1 = x1 + i y1, z2 = x2 + i y2
//
// z1*z2 = ( x1 + i y1 )*( x2 + i y2 )
// = ( x1*x2 + i x1*y2 + i x2*y1 - y1*y2
// = ( x1*x2 - y1*y2 ) + i ( x1*y2 + x2*y1 )

float x1 = re, y1 = im, x2 = z.re , y2 = z.im;

return Complex( x1*x2 - y1*y2, x1*y2 + x2*y1 );
}

Complex Complex::eek:perator/( Complex &z )
{
// z1 = x1 + i y1, z2 = x2 + i y2
//
// z1 z1 z2* z1*z2 z1*z2
// -- = -- -- = ------ = -------------
// z2 z2 z2* |z2|^2 x1*x1 + y1*y1
//
// z1*z2 = ( x1*x2 - y1*y2 ) + i ( x1*y2 + x2*y1 )
//
// z1 x1*x2 - y1*y2 x1*y2 + x2*y1
// -- = ----------------- + i -------------
// z2 x1*x1 + y1*y1 x1*x1 + y1*y1
//
// a = x1*x2 - y1*y2, b = x1*y2 + x2*y1, c = x1*x1 + y1*y1
//
// z1 a b
// -- = -- + i -- = x + i y
// z2 c c
//
// x = a/c, y = b/c
//
float x1 = re, y1 = im, x2 = z.re , y2 = z.im;
float a, b, c, x, y;

a = x1*x2 - y1*y2;
b = x1*y2 + x2*y1;
c = x1*x1 + y1*y1;
x = a/c;
y = b/c;

return Complex( x, y );
}

Complex Complex::eek:perator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}


Complex Complex::conjugate()
{
return Complex( re, -im);
}

float Complex::magnitude()
{
return sqrt( re*re + im*im );
}

int main()
{
Complex u( 1, 5 ), v( 2, 2 ), w( 1, 1 );
Complex uConj, sum, prod, diff, ratio;
float r;

uConj = u.conjugate();
r = u.magnitude();

cout << "\nu = " << u << endl;
cout << "\nv = " << v << endl;
cout << "\nu* = " << uConj << endl;
cout << "\n|u| = " << r << endl;

sum = u + v;
diff = u - v;
prod = u*v;
ratio = u/v;

cout << "\nu + v = " << sum << endl;
cout << "\nu - v = " << diff << endl;
cout << "\nu*v = " << prod << endl;
cout << "\nu/v = " << ratio << endl;

sum = u + v + w;
cout << "\nu + v + w = " << sum << endl;

return 0;
}
_____________________________________________
 
J

John Harrison

Pmb said:
There wasn't an "ostream" issue. I simply didn't post the entire code. I
suppose I should have in retrospect. The following is the compile error I
get from the program below

-----------------
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
d:\temp\test\example.cpp:
Error E2285 d:\temp\test\example.cpp 130: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 138: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 139: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 140: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 141: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
Error E2285 d:\temp\test\example.cpp 148: Could not find a match for
'Complex::eek:perator =(Complex)' in function main()
*** 6 errors in Compile ***

Tool completed with exit code 1
------------------

Line 130 is " uConj = u.conjugate();"
Lines 138-141 are

138 "sum = u + v;"
139 "diff = u - v;"
140 "prod = u*v;"
141 "ratio = u/v;"


What am I doing wrong this time?

Forgetting const, put the const in and it will compile.

Complex& operator=(const Complex & );

What you are failing to realise is that you cannot bind a temporary to a
non-const reference.

sum = u + v;

u + v returns a temporary, you have declared your operator= with a non-const
reference. Therefore you cannot use u + v on the right hand side of a
operator=.

Just add const.

john
 
P

Pmb

John Harrison said:
Forgetting const, put the const in and it will compile.

Complex& operator=(const Complex & );

What you are failing to realise is that you cannot bind a temporary to a
non-const reference.

I see no reason for that to be true.
sum = u + v;

u + v returns a temporary, you have declared your operator= with a non-const
reference. Therefore you cannot use u + v on the right hand side of a
operator=.

Just add const.

I disagree. I simplified the code I'm working on to the bare bones. It now
reads

_______________________________________
#include <iostream.h>

class Complex {
public:
Complex( float = 0.0, float = 0.0 );
Complex &operator=( Complex & );
float getRe() { return re; };
float getIm() { return im; };
private:
float re;
float im;
};

Complex::Complex( float a, float b )
: re( a ), im( b) { }

Complex& Complex::eek:perator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}


int main()
{
Complex z1( 1, 5 ), z2( 0, 0 );
float x, y;

x = z2.getRe();
y = z2.getIm();

cout << "Components before 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

z2 = z1;

x = z2.getRe();
y = z2.getIm();

cout << "\nComponents after 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

return 0;
}
_______________________________________

This program works just fine. The output is

------------
Components before 'operator=' call: (x,y) = (0,0)

Components after 'operator=' call: (x,y) = (1,5)
------------

That is exactly what I want it to do. Had I wanted to use this code further
then perhaps I'd used const's. Not while I'm in a learning mode. When
learning one seeks to understand when something is required and when it is
not required and how it affects the logic etc. Perhaps everyone disagrees
with the way I chose to learn. But that is the way I choose to learn

Pmb
 
J

John Harrison

I see no reason for that to be true.

You might not see a reason, other people don't see the reason, its somewhat
controversial, but its in the C++ standard in black and white. However some
compilers do not enforce that rule.
I disagree. I simplified the code I'm working on to the bare bones. It now
reads

Fine but you've changed the program to avoid the problem I described. You no
longer have a temporary on the rhs of an assignment.
_______________________________________
#include <iostream.h>

class Complex {
public:
Complex( float = 0.0, float = 0.0 );
Complex &operator=( Complex & );
float getRe() { return re; };
float getIm() { return im; };
private:
float re;
float im;
};

Complex::Complex( float a, float b )
: re( a ), im( b) { }

Complex& Complex::eek:perator=( Complex &z )
{
re = z.re;
im = z.im;

return *this;
}


int main()
{
Complex z1( 1, 5 ), z2( 0, 0 );
float x, y;

x = z2.getRe();
y = z2.getIm();

cout << "Components before 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

z2 = z1;

x = z2.getRe();
y = z2.getIm();

cout << "\nComponents after 'operator=' call: (x,y) = ("
<< x << "," << y << ")" << endl;

return 0;
}
_______________________________________

This program works just fine. The output is

------------
Components before 'operator=' call: (x,y) = (0,0)

Components after 'operator=' call: (x,y) = (1,5)
------------

That is exactly what I want it to do. Had I wanted to use this code further
then perhaps I'd used const's. Not while I'm in a learning mode. When
learning one seeks to understand when something is required and when it is
not required and how it affects the logic etc. Perhaps everyone disagrees
with the way I chose to learn. But that is the way I choose to learn

I was just answering the question you asked, 'What have I done wrong this
time?' I pointed out a way (the only way) to make your program compile, you
chose to write a different program instead.

john
 
P

Pmb

John Harrison said:
You might not see a reason, other people don't see the reason, its somewhat
controversial, but its in the C++ standard in black and white. However some
compilers do not enforce that rule.


Fine but you've changed the program to avoid the problem I described. You no
longer have a temporary on the rhs of an assignment.


I was just answering the question you asked, 'What have I done wrong this
time?' I pointed out a way (the only way) to make your program compile, you
chose to write a different program instead.

I think I see what you're saying. This is why I left the const's out -
learning purposes. If what you say is true (and I now see that perhaps it
is) then I would have missed this point had I put them in solely for the
purpose of good programming practice. Now I know that there are
circumstances where leaving the const out causes compile errors.

Thanks

Pmb
 
J

John Harrison

I think I see what you're saying. This is why I left the const's out -
learning purposes. If what you say is true (and I now see that perhaps it
is) then I would have missed this point had I put them in solely for the
purpose of good programming practice. Now I know that there are
circumstances where leaving the const out causes compile errors.

Thanks

Pmb

In C there's a notion which says that any legal program that uses const
would also be a legal program if all the consts were removed. That has never
been true in C++.

john
 
P

Pmb

John Harrison said:
In C there's a notion which says that any legal program that uses const
would also be a legal program if all the consts were removed. That has never
been true in C++.

What does the C++ standard say on this issue?

Pmb
 
P

Pmb

----- Original Message -----
From: "John Harrison" <[email protected]>
Newsgroups: comp.lang.c++
Sent: Saturday, May 29, 2004 7:50 AM
Subject: Re: Overloading the "=" operator for Complex numbers

In C there's a notion which says that any legal program that uses const
would also be a legal program if all the consts were removed. That has never
been true in C++.

While I now understand that I *must* put const in I still don't understand
*why* I must do that? You wrote
What you are failing to realise is that you cannot bind a temporary to a
non-const reference.

What does "bind a temporary" mean?
sum = u + v;

u + v returns a temporary, ...

Please clarify. What do you mean by "returns a temporary"? I assume that
you're referring to the return value of

Complex Complex::eek:perator+( Complex &z )

Since this is a temporary and since this is what goes into the input of

Complex& Complex::eek:perator=( const Complex &z )

Then shouldn't the input be temporary?
...you have declared your operator= with a non-const
reference.

Doesn't "non-constant" mean "temporary"?

Thanks

Pmb

ps - Sorry. I accidently sent this to your e-mail too
 
J

JKop

Pmb posted:

While I now understand that I *must* put const in I still don't
understand *why* I must do that?


int a = 6;
const int b = 5;
const int c = 4;


a = b;


Self explanatory I hope.

What does "bind a temporary" mean?

unsigned int GiveNumber(void)
{
return 27;
}

int main(void)
{
int& given_number = GiveNumber();


given_number = 27; //Guess what happens here...

//The object returned from GiveNumber no longer exists, I have
//a hanging pointer, in the form of a reference. And I just accessed
//"unallocated" memory, memory that ain't mine. BOLD!
}
 
J

Jeff Relf

Hi Pmb, ( and all you C++ guys too ) [ Posted & e-mailed ]

You showed, " sum = u + v; ".

And in your e-mail to me you showed:
cin >> "Enter z = x + i y: " >> z;

I'd be nice if one could say:
cin >>
"Enter z, ( in the form: Real + Imaginary ): " >> z;

Then the user could simply type in something like:
5 + 6

But you can't overload the + symbol like that,
because it reacts to the type of the operands,
which, in this case, are not even reals,
much less complex. ( They are integers )

Could that be solved by
using something other than the + symbol ?

Correct me if I'm wrong here C++ guys,
but I think the only solution is
to use string input like this:

float Real; String A_String_Operator; float Imaginary;
cin >>
"Enter z,"
" ( in the form: Real + Imaginary, "
" spaces required ): " >>
Real >> A_String_Operator >> Imaginary;

Then the user could simply type in something like:
5 + 6
 
J

John Carson

Pmb said:
----- Original Message -----
From: "John Harrison" <[email protected]>

While I now understand that I *must* put const in I still don't
understand *why* I must do that? You wrote


What does "bind a temporary" mean?

A reference refers to an object. A reference is "bound to a temporary" when
it is made to refer to a temporary. The binding takes place in this instance
when the temporary is passed as the operator argument.
Please clarify. What do you mean by "returns a temporary"? I assume
that you're referring to the return value of

Complex Complex::eek:perator+( Complex &z )
Correct.

Since this is a temporary and since this is what goes into the input
of

Complex& Complex::eek:perator=( const Complex &z )

Then shouldn't the input be temporary?

Yes, the input is a temporary. But the reference is a const reference. You
are allowed to bind temporaries to const references, but not to non-const
references.
Doesn't "non-constant" mean "temporary"?

No. const and non-const has to do with the right to modify an object. When
you declare an operator with

Complex& Complex::eek:perator=(Complex &z );

the operator has the right to modify whatever is passed in as its argument.
Thus the assignment in

z = u;

would allow u to be modified by the assignment operator. By contrast, a
declaration of

Complex& Complex::eek:perator=( const Complex &z );

means that the assignment operator is not allowed to modify its argument (u
in the above example).

Why is only the second version allowed when the argument is a temporary?
This is to prevent programmers from making a particular type of error. If a
function or operator modifies its argument, then that usually means that the
programmer wishes to change the object in the scope from which the function
or operator has been called, as in the following example:

void DoubleValue(int &n)
{
n *=2;
}

int main()
{
int m = 2;
DoubleValue(m);
// m will now be 4
}

Now if the argument passed to a function is a temporary, then the function's
action will change the value of the temporary, but the temporary will cease
to exist as soon as the function returns. Thus the function will not have an
effect in the scope from which it is called. This may be an unpleasant
surprise to the programmer, so the language prevents the passing of
temporaries to functions and operators with non-const reference parameters
in order to eliminate the possibility of this unpleasant surprise. The risk
of this surprise is greater than you might think because temporaries get
generated in more cases than you might think.
 
J

John Harrison

Pmb said:
----- Original Message -----
From: "John Harrison" <[email protected]>
Newsgroups: comp.lang.c++
Sent: Saturday, May 29, 2004 7:50 AM
Subject: Re: Overloading the "=" operator for Complex numbers



While I now understand that I *must* put const in I still don't understand
*why* I must do that? You wrote

non-const reference.

What does "bind a temporary" mean?


Please clarify. What do you mean by "returns a temporary"? I assume that
you're referring to the return value of

Complex Complex::eek:perator+( Complex &z )

Since this is a temporary and since this is what goes into the input of

Complex& Complex::eek:perator=( const Complex &z )

Then shouldn't the input be temporary?


Doesn't "non-constant" mean "temporary"?

Thanks

Pmb

A temporary is an unnamed object. 'u + v' returns a Complex object, but that
object has no name, so it's a temporary (the compiler creates it when the
functions returns and destroys it when it been used, hence its called a
temporary). Any function or operator that returns an object returns a
temporary. There are various other ways to create temporaries

class X
{
public:
X(int x);
};

void f(const X& x);

f(1);

There's a constructor for X that takes an int, so when you try to call f
using an int, the compiler creates a temporary X from the int and uses that
to call f.

You can also create temporaries explicitly

Complex z = Complex(1.0, 2.0) + Complex(3.0, 4.0);

The objects created by Complex(1.0, 2.0) and Complex(3.0, 4.0) have no name,
they are temporaries.

When a reference is initialised its usually referred to as binding a
reference.

int x;
int& y = x; // y is bound to x

Now the crunch, a temporary cannot be bound to a non-const reference.
Suppose you have written

class Complex
{
public:
Complex operator+(Complex& rhs);

Now this is illegal

Complex z = Complex(1.0, 2.0) + Complex(3.0, 4.0);

The right hand side of your operator+ is a temporary but you operator+ has
been written with a non-const reference, so the above should not compile.
Similarly

Complex f();

Complex z = Complex(1.0, 2.0) + f();

Again the right hand side is a temporary.

Why does C++ have this rule? That's a good question, Bjarne Stroustrup says
that it leads to code that is too confusing, he has in mind code like this

void trim_whitespace(string& s); // removes whitespace from s

trim_whitespace(" abc ");

Without the 'can't bind a temporary to a non-const reference' rule the
compiler would create a temporary string from " abc ", that would be passed
to trim_whitespace, which would faithfully remove the whitespace, but when
the function returns the temporary (with its whitespace removed) would be
destroyed. The original string literal " abc " would be completely
untouched.

With the rule the above will not compile, which it what you would want.

As I said this isn't uncontroversial, but it is the way C++ is. If you want
to consult the standard 8.5.3 para 5

john
 

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,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top