Что выводит условный оператор с унарным оператором

У меня есть следующий код, поведение которого мне непонятно. Может кто-нибудь, пожалуйста, помогите, как условный оператор оценивает следующий код и выводит ответ как 1

#включать

int main() {

bool delayMessages=0;
bool Delay = false;
delayMessages += Delay ? 1 : -1;
std::cout << "Hello world!"<<delayMessages;

return 0;
} 

Ans: Hello world!1

Может кто-нибудь помочь, как оценивается этот код "delayMessages += Delay? 1: -1;"

delayMessages должен быть целочисленным, а не логическим типом
perivesta 18.03.2022 09:41
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
39
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Выражение в правой части оценивается как оператор if.

if (Delay == true)
   return 1;
else
   return -1;

Затем результат используется для присвоения +=.

в Стандарт черновик С++ 20, который

7.6.19 (6) (Assignment and compound assignment operators)

The behavior of an expression of the form E1 op= E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once. [...]

Поскольку Delay == false, тернарный оператор возвращает значение -1. Тот факт, что вы работаете с boolean вместо int, может создать впечатление, что вы получили +1 обратно.

Обратите внимание, что вы получаете предупреждение компилятора C4804:

warning C4804: '+=': unsafe use of type 'bool' in operation

Это неопределенное поведение? Нет.

7.6.19 (6) (Assignment and compound assignment operators)

[...] For += and -=, E1 shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object type. In all other cases, E1 shall have arithmetic type.

и

7.3.8 (2) (Integral conversions)

If the destination type is bool, see 7.3.14.

что говорит

7.3.14 (1) (Boolean conversions)

A prvalue of arithmetic, unscoped enumeration, pointer, or pointer-to-member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true.

Таким образом, -1 преобразуется в true, а true печатается как 1.

 Delay ? 1 : -1

оценивается как -1, потому что Delay ложно. Преобразование -1 в bool дает true, потому что только 0 преобразуется в false. Затем распечатайте true отпечатки 1. Результат true независимо от того, является ли Delaytrue или false и 1 печатается в обоих случаях.

Используйте true / false для логических значений и используйте целочисленный тип для целых чисел. Возможно, это то, что вы на самом деле хотели сделать:

int delayMessages=0;
bool Delay = false;
delayMessages += Delay ? 1 : -1;
std::cout << "Hello world!"<<delayMessages;
delayMessages += Delay ? 1 : -1;

В основном это означает, что если Delay верно, то delayMessages += 1 (что равно 1), иначе delayMessages += -1 (что также равно 1).

Из стандарта C++ 17 (интегральные акции 7.6)

6 A prvalue of type bool can be converted to a prvalue of type int, with false becoming zero and true becoming one.

и (7.14 логические преобразования)

1 A prvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to a prvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. For direct-initialization (11.6), a prvalue of type std::nullptr_t can be converted to a prvalue of type bool; the resulting value is false.

и наконец (8.7 Аддитивные операторы)

1 The additive operators + and - group left-to-right. The usual arithmetic conversions are performed for operands of arithmetic or enumeration type.

Этот оператор выражения

delayMessages += Delay ? 1 : -1;

можно переписать как

delayMessages = delayMessages + ( Delay ? 1 : -1 );

Результатом выражения с условным оператором является -1, потому что первое подвыражение (Delay) оценивается как false.

Так что на самом деле у вас есть

delayMessages = delayMessages + -1;

Переменная delayMessage объявлена ​​как

bool delayMessages=0;

имеет значение false согласно цитатам из раздела 7.14.

В выражении с бинарным оператором плюс + преобразуется в целое число 0 согласно кавычкам (7.6 Интегральные промоушены) и 8.7 Аддитивные операторы и у вас есть

delayMessages = 0 + -1;

или

delayMessages = -1;

Опять же, согласно цитате 7.14 Логические преобразования, результирующее значение переменной delayMessage будет true.

Оператор << выводит логическое значение true как 1 в этом выражении.

std::cout << "Hello world!"<<delayMessages;

Другие вопросы по теме