What is the logical operation AND works with the stream?

I just saw the code, and I can't figure out how logical and behaves with "cout" here:

int userInput = 9; // Suppose user input is 9. int remainder = 9 % 2; (remainder & 1 && std::cout<<"odd" )|| cout<<"even"; 
+5
source share
2 answers

Corresponding line:

 (remainder & 1 && std::cout<<"odd" ) || cout<<"even"; 

The same as when using operator priority and operator overload :

 ((remainder & 1) && (operator<<(std::cout, "odd").operator bool())) || (operator<<(std::cout, "even").operator bool()); 

std::cout (more general, std::basic_ostream ) has the operators operator<<() and operator bool() . The first statement returns the link std::basic_ostream& , i.e. Link to the thread itself (useful for chaining operations together). The second statement returns whether the thread is in a failed state or not.

See the following documentation for more information:

priority C ++ operators

operator overload

std :: basic_ostream :: operator <<

std :: basic_ios :: operator bool

+6
source

std::cout<<"odd" is an expression that std::cout will return (which is why you can do std::cout << a << b << c ). When evaluated in a boolean context, it simply returns true if the failure bit is not set. Therefore, if the output operation completes successfully, it will be evaluated as true.

However, the purpose of this code is not to check this value, rather it is a smart (and not very readable) method 1 :

 if (remainder & 1) { std::cout << "odd"; } else { std::cout << "even"; } 

It exploits the short-circuited nature of the && and || :

  • In a && b , if a is false, then it is evaluated as a ( b not evaluated!), Otherwise it is evaluated as b .
  • In a || b a || b , if a true, then it is evaluated as a ( b not evaluated!), otherwise it is evaluated as b .

So, if remainder & 1 evaluates to false (in this case, zero), then std::cout << "odd" not evaluated, because the expression && short circuit that returns false. This is the left operand of the external expression || , which causes an evaluation of its b ( std::cout << "even" ), writing "even" to the output.

If remainder & 1 evaluates to true (in this case, nonzero), then the right operand for && evaluates to an odd mapping. Assuming this operation succeeds, the left operand for the operation || will be true, which will lead to its short circuit and will not evaluate the right operand.


1 Experienced programmers probably know exactly what is happening here, but, as you understand, this method is not the most readable. It is better (IMO) to understand the intent of the code, so I would just use a conditional if - or at least use the ternary operator: std::cout << (remainder & 1 ? "odd" : "even") .

In other languages ​​(JavaScript comes to mind) (ab) using short-circuited operators is a very common method. Usually I don’t see them using this method in C ++, and I would strongly discourage such use.

+13
source

Source: https://habr.com/ru/post/1206605/


All Articles