Output of Cout function in C++ [duplicate] - c++

By trying, I came to know that it is necessary to put parentheses around a conditional operator in a cout statement. Here a small example:
#include <iostream>
int main() {
int a = 5;
float b = (a!=0) ? 42.0f : -42.0f;
// works fine
std::cout << b << std::endl;
// works also fine
std::cout << ( (a != 0) ? 42.0f : -42.0f ) << std::endl;
// does not work fine
std::cout << (a != 0) ? 42.0f : -42.0f;
return 0;
}
The output is:
42
42
1
Why are these parentheses necessary? The resulting type of the conditional operator is known in both cases, isn't it?

The ?: operator has lower precedence than the << operator i.e., the compiler interprets your last statement as:
(std::cout << (a != 0)) ? 42.0f : -42.0f;
Which will first stream the boolean value of (a!=0) to cout. Then the result of that expression (i.e., a reference to cout) will be cast to an appropriate type for use in the ?: operator (namely void*: see cplusplus.com), and depending on whether that value is true (i.e., whether cout has no error flags set), it will grab either the value 42 or the value -42. Finally, it will throw that value away (since nothing uses it).

Because << has higher precedence than ?.
Fun exercise:
float ftest = std::cout << (a != 0) ? 42.0f : -42.0f;
Take that, Coding Horror!!!
Your code is equivalent to:
if ( std::cout << (a != 0) )
42.0f;
else
-42.0f;
It outputs 1 because, well, (a != 0) == true;

By the way, this can also work:
a != 0 ? std::cout << 42.0f : std::cout << -42.0f;
In my opinion it is better to use this way because:
It also works in the case, where we want to output different data types (telling from my experience)
For example, if had to do something like this:
std::cout << (a != 0 ? 42.0f : "Not zero!");
Will generate an error because one expression is of float type and the other is of char* type, but you can write it like this :
a != 0 ? std::cout << 42.0f : cout << "Not zero!";
This works because expressions in the conditional statement must have same data type value, and std::cout returns the same data type no matter what it is being output through it.
(Minor reason) No parenthesis - You don't have to deal with parenthesis as << have higher precedence over ?: as stated in the above answers as well. This can save us the hassle of matching closing brackets thereby reducing probability of error.

Related

I have a problem with the '?' operator. Why doesn't this line do what it should? [duplicate]

By trying, I came to know that it is necessary to put parentheses around a conditional operator in a cout statement. Here a small example:
#include <iostream>
int main() {
int a = 5;
float b = (a!=0) ? 42.0f : -42.0f;
// works fine
std::cout << b << std::endl;
// works also fine
std::cout << ( (a != 0) ? 42.0f : -42.0f ) << std::endl;
// does not work fine
std::cout << (a != 0) ? 42.0f : -42.0f;
return 0;
}
The output is:
42
42
1
Why are these parentheses necessary? The resulting type of the conditional operator is known in both cases, isn't it?
The ?: operator has lower precedence than the << operator i.e., the compiler interprets your last statement as:
(std::cout << (a != 0)) ? 42.0f : -42.0f;
Which will first stream the boolean value of (a!=0) to cout. Then the result of that expression (i.e., a reference to cout) will be cast to an appropriate type for use in the ?: operator (namely void*: see cplusplus.com), and depending on whether that value is true (i.e., whether cout has no error flags set), it will grab either the value 42 or the value -42. Finally, it will throw that value away (since nothing uses it).
Because << has higher precedence than ?.
Fun exercise:
float ftest = std::cout << (a != 0) ? 42.0f : -42.0f;
Take that, Coding Horror!!!
Your code is equivalent to:
if ( std::cout << (a != 0) )
42.0f;
else
-42.0f;
It outputs 1 because, well, (a != 0) == true;
By the way, this can also work:
a != 0 ? std::cout << 42.0f : std::cout << -42.0f;
In my opinion it is better to use this way because:
It also works in the case, where we want to output different data types (telling from my experience)
For example, if had to do something like this:
std::cout << (a != 0 ? 42.0f : "Not zero!");
Will generate an error because one expression is of float type and the other is of char* type, but you can write it like this :
a != 0 ? std::cout << 42.0f : cout << "Not zero!";
This works because expressions in the conditional statement must have same data type value, and std::cout returns the same data type no matter what it is being output through it.
(Minor reason) No parenthesis - You don't have to deal with parenthesis as << have higher precedence over ?: as stated in the above answers as well. This can save us the hassle of matching closing brackets thereby reducing probability of error.

Ternary operator compilation

Why does this giving compilation problem at bold line?
#include<iostream>
static int i = 10;
int main() {
**(i) ? (std::cout << "First i = " << i << std::endl) : ( i = 10);**
std::cout << "Second i = " << i << std::endl;
}
Compilation message:
test.c:8: error: invalid conversion from ‘void*’ to ‘int’
Your usage of the ternary operator is a bit weird: based on the value of i, you either print something to std::cout or assign a new value to it. Those actions don't share a connection through the return value of an expression, so don't do it like this. When using the ternary operator, it's best to stay closer to its intended purpose: a short notation for two possible expressions with a dispatch based on a simple predicate. Example:
const int n = i == 0 ? 42 : 43;
Your code should look like this:
if (i == 0)
i = 10;
else
std::cout << "First i = " << i << "\n";
The reason the original snippet did not compile is that there is no common return type of the ternary operator. "Common" means that both expressions can be converted to the return type. E.g., in const int n = i == 0 ? 42 : 43; the return type is int.
The problem comes from the fact that the return values of the expressions in your conditional operator (ternary operator) (std::ofstream in the case of the std::cout ..., and int for i = 10) are incompatible and therefore the conditional operator is ill-formed. Please check the rules for return type of the conditional operator.
In this case, just use a normal conditional:
if (i)
std::cout << "First i = " << i << std::endl;
else
i = 10;

About shift operator trick in C++?

When I was reading the code in Google Protocol Buffers, I found confused code as follows.
1 < 2 ? (void)0 : cout << "hi" << endl;
The point is that the string "hi' will pipe through NULL by the left shift operator. As a result, nothing happened. That means this is correct code grammatically.
And I tried out little bit different code as below.
(void)0 << "hi" << endl;
Of course, It didn't work.
Lastly, I tried out this code.
string tmp;
cin >> (1 < 2 ? 0 : tmp);
It was compiled but crashed in runtime. (It works if the sign is changed inversely but the input is not stored in tmp.)
Is there someone who can walk me though what to happen in the first case? (in terms of compiler or low level if possible)
You're misreading it, 1 < 2 ? (void)0 : cout << "hi" << endl; translates to :
if(1 < 2) {
(void)0; //do nothing
} else {
cout << "hi" << endl;
}
condition ? true-state : false-state; is called a ternary operator, it absolutely has nothing to do with <<.
<< has higher precedence than ?:, so:
1 < 2 ? (void)0 : cout << "hi" << endl;
is actually equivalent to:
(1 < 2) ? (void)0 : (cout << "hi" << endl);
not to:
((1 < 2 ? (void)0 : cout)) << "hi" << endl;
(And, of course condition ? then_expression : else_expresion won't evaluate else_expression at all if condition is true.)
1 < 2 ? (void)0 : cout << "hi" << endl;
The other answers have pointed out that the operator precedence gives this a different meaning from what you assumed, so the above is equivalent to:
(1 < 2)
? (void)0
: (cout << "hi" << endl);
But it's still illegal.
If the second or third operand of the ?: conditional operator is of type void, then the other must also be of type void or must be a throw-expression.
Casting the third operand to void would address that:
1 < 2 ? (void)0 : (void)(cout << "hi" << endl);
If you can update your question to show the exact code you're asking about, we can probably explain it better.
It would also be interesting to see the context in which this appears. By itself, it would be much more legible as an if statement.

Cout String and int in ternary operator

A line in my c++ code reads:
cout<<(i%3==0 ? "Hello\n" : i) ;//where `i` is an integer.
But I get this error:
operands to ?: have different types 'const char*' and 'int
How can I modify the code (with minimum characters)?
Ugly:
i%3==0 ? cout<< "Hello\n" : cout<<i;
Nice:
if ( i%3 == 0 )
cout << "Hello\n";
else
cout << i;
Your version doesn't work because the result types of the expressions on each side of : need to be compatible.
You can't use the conditional operator if the two alternatives have incompatible types. The clearest thing is to use if:
if (i%3 == 0)
cout << "Hello\n";
else
cout << i;
although in this case you could convert the number to a string:
cout << (i%3 == 0 ? "Hello\n" : std::to_string(i));
In general, you should try to maximise clarity rather than minimise characters; you'll thank yourself when you have to read the code in the future.
operator<< is overloaded, and the two execution paths don't use the same overload. Therefore, you can't have << outside the conditional.
What you want is
if (i%3 == 0) cout << "Hello\n"; else cout << i;
This can be made a bit shorter by reversing the condition:
if (i%3) cout << i; else cout << "Hello\n";
And a few more characters saved by using the ternary:
(i%3)?(cout<<i):(cout<<"Hello\n");
std::cout << i % 3 == 0 ? "Hello" : std::to_string(i);
But, as all the other answers have said, you probably shouldn't do this, because it quickly turns into spaghetti code.

Conditional operator used in cout statement

By trying, I came to know that it is necessary to put parentheses around a conditional operator in a cout statement. Here a small example:
#include <iostream>
int main() {
int a = 5;
float b = (a!=0) ? 42.0f : -42.0f;
// works fine
std::cout << b << std::endl;
// works also fine
std::cout << ( (a != 0) ? 42.0f : -42.0f ) << std::endl;
// does not work fine
std::cout << (a != 0) ? 42.0f : -42.0f;
return 0;
}
The output is:
42
42
1
Why are these parentheses necessary? The resulting type of the conditional operator is known in both cases, isn't it?
The ?: operator has lower precedence than the << operator i.e., the compiler interprets your last statement as:
(std::cout << (a != 0)) ? 42.0f : -42.0f;
Which will first stream the boolean value of (a!=0) to cout. Then the result of that expression (i.e., a reference to cout) will be cast to an appropriate type for use in the ?: operator (namely void*: see cplusplus.com), and depending on whether that value is true (i.e., whether cout has no error flags set), it will grab either the value 42 or the value -42. Finally, it will throw that value away (since nothing uses it).
Because << has higher precedence than ?.
Fun exercise:
float ftest = std::cout << (a != 0) ? 42.0f : -42.0f;
Take that, Coding Horror!!!
Your code is equivalent to:
if ( std::cout << (a != 0) )
42.0f;
else
-42.0f;
It outputs 1 because, well, (a != 0) == true;
By the way, this can also work:
a != 0 ? std::cout << 42.0f : std::cout << -42.0f;
In my opinion it is better to use this way because:
It also works in the case, where we want to output different data types (telling from my experience)
For example, if had to do something like this:
std::cout << (a != 0 ? 42.0f : "Not zero!");
Will generate an error because one expression is of float type and the other is of char* type, but you can write it like this :
a != 0 ? std::cout << 42.0f : cout << "Not zero!";
This works because expressions in the conditional statement must have same data type value, and std::cout returns the same data type no matter what it is being output through it.
(Minor reason) No parenthesis - You don't have to deal with parenthesis as << have higher precedence over ?: as stated in the above answers as well. This can save us the hassle of matching closing brackets thereby reducing probability of error.