cout with math

1
2
3
4
5
6
7
8
9
10
#include<iostream>     
               
using namespace std;
int main()
{
int x=4;
int y = 10 ;
cout<<y+=x;

}


can we use cout like this : cout<<y+=x;? and if no why?
Does your compiler have any opinion on the matter?
yes it says:

[Error] no match for 'operator+=' (operand types are 'std::basic_ostream<char>' and 'int')

what does the error mean ?

You essentially have Z += x where we know that x is an int, so the Z has type std::basic_ostream<char>.

The y is an int too, so the Z is not y.

The operator<< returns a reference to the stream and that matches the Z.


In other words:
1
2
3
4
5
6
7
8
cout << y += x;

// is same as
cout << y;
cout += x;

// is same as
( cout << y ) += x;

What you see is the result of operator precedence rules.

See the end of http://www.cplusplus.com/doc/tutorial/operators/
I was a little bit confused by keskiverto's explanation.
So here's my attempt.

y += x;
is the same as
y = y + x;

So I believe it's not compiling because you're initializing a variable after a output operand.

Here's you would fix it.
1
2
3
4
5
6
7
8
9
10
11
#include<iostream>     
               
using namespace std;
int main()
{
int x=4; // your declaring x as an int and initializing it to 4
int y = 10 ;  // your declaring y as an int and initializing it to 10
y += x; // you reinitializing y as the sum of x & y.
cout << y;

}
Last edited on
Add parenthesis cout << (y+=x);
Last edited on
@Momothegreat

Do you mean assigning to a variable? (it's not usually referred to as reinitializing!)

As keskiverto ended his post by saying, the issue is operator precendence.

I can assign to a variable in an output statement it I use brackets to force the order of evaluation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

int main()
{
    int i = 1;
    int j = 2;
    int k = 3;

    // no need for brackets as + and * are higher precedence
    cout << "i + j -> " << i + j << "\n";
    cout << "i * j + k -> " << i * j + k << "\n";

    // need brackets as = and += are lower precendence
    cout << "j += 2 -> " << (j += 2) << "\n";
    cout << "k = i + j -> " << (k = i + j) << "\n";

    return 0;
}


Andy
Last edited on
"I was a little bit confused by keskiverto's explanation"

me too but not little otherwise a lot

"You essentially have Z += x where we know that x is an int, so the Z has type std::basic_ostream<char>.

The y is an int too, so the Z is not y"

which Z are you talking about ?!! do you see any Z in my little piece of code !!?

Momothegreat I did not understand what do you mean by :

"So I believe it's not compiling because you're initializing a variable after a output operand."









"Add parenthesis cout << (y+=x);"

Thank you very much for this answer . It is clear .

Why should we use the parenthesis to get no error ?

for example:

1
2
3
4
5
6
int main()
{
int x = 4;
int y = 10;
cout<<y*x;
}


gives 40 .

we did not use parenthesis and we got no error

why here cout<<y*x; we did not use parenthesis but we got no error meanwhile here

cout<<y+=x we used no parenthesis and we got error? what is the difference? why should we use parenthesis in cout<<y+=x
Last edited on
why here cout<<y*x; we did not use parenthesis but we got no error

As has already been said, it's down to order of precendence.

Have you looked at the tutorial keskiverto pointed you at?

Operators
http://www.cplusplus.com/doc/tutorial/operators/

The table at the end (in the "Precedence of operators" sections) shows that operator* has precedence level 5, whereas operator<< has level 7 and operator+= has 15.

And when evaluating an expression, the higher level (1 is highest) operators are evaluated before the lower level ones. So * is evaluated before << but << is evaluated before +=.

When operator* is evaluated first, all is OK as operator* returns a value of the same type as its operands. e.g. <int> * <int> -> <int> in this case, and operator<< knows how to write out the resultant int.

When operator<< is evaluated first, before +=, it all goes wrong. The overload for writing ints (omitting the std namespace qualifier) is ostream& operator<<(ostream&, int) So its the temporary ostream returned by the evalution of cout << y that you're trying to increment with +=x, But ostream does not support this operator so it doesn't work.

Andy

PS It is a bit confusing that the bitwise shift operator is overloaded for stream insertions (that is, output), but it has the same precedence when used for stream operations as bitwise ones.

Why are bitwise shifts (<< and >>) used for cout and cin?
http://stackoverflow.com/questions/4854248/why-are-bitwise-shifts-and-used-for-cout-and-cin
Last edited on
@dlvir
My bad man, I was wrong. I meant to say assigning a variable after an output operand. But it seems you can have assignment statements in your output, they just need to be formatted correctly. In this case you need to pay attention to the order of operations in C++ logic executions.
which Z are you talking about ?!! do you see any Z in my little piece of code !!?

It does not matter what I see or don't see. Your compiler says:
operand types are 'std::basic_ostream<char>' and 'int'

Therefore, it does see an ostream as the left operand of +=.

That left operand is an unnamed temporary object that is what the operator << does return in your statement. I could have repeated the "unnamed temporary rvalue object that cannot be referred to with any name" in my nebulous narration, but chose to use a shorter random name "Z". My mistake.
Topic archived. No new replies allowed.