Подтвердить что ты не робот

Почему оператор `?:` Не имеет приоритета?

После отладки я обнаружил, что тернарный оператор ?: не имеет приоритета. Мой вопрос: почему? У меня есть следующий код:

bool T = true;
cout << ((T == true) ? "true" : "false") << endl;
cout << (T == true) ? "true" : "false";

Выход:

true
1

live demo: http://ideone.com/Tkvt9q

4b9b3361

Ответ 1

Условный оператор имеет приоритет (хотя и слегка усложненный его тройственным характером); но этот приоритет очень низок. Поскольку он меньше, чем <<, второй анализируется как

(cout << (T == true)) ? "true" : "false";

потоковое булевское значение T == true, затем оценивая (но игнорируя) выражение "true". Большинство компиляторов выдаст предупреждение, если вы включите разумный набор предупреждений.

Вот ссылка на приоритеты операторов, показывающая << с более высоким приоритетом (7), чем ?: (15): http://en.cppreference.com/w/cpp/language/operator_precedence

Ответ 2

У условного оператора ? : есть приоритет - это номер 15 в этой таблице, ниже, чем << и >> операторы, которые являются номером семь.

Правило, которое я придерживаюсь, чтобы избежать подобных ошибок, заключается в использовании круглых скобок, когда вы сомневаетесь. Обоснование прост: если вам нужно найти приоритет в таблице, есть хорошие шансы, что читатели вашего кода, включая вас самих, должны будут сделать то же самое в более позднее время.

Ответ 3

Многие другие вопросы отвечают, почему вы видите это поведение, но не отвечаете, почему тернарный оператор имеет низкий приоритет.

Было принято решение иметь низкий тройной приоритет, потому что нам не нужен код

a<d ? 10 : 100

в конечном итоге означает

a < (d ? 10 : 100) //BAD: not what we normally expect

мы хотим, чтобы это означало

(a<d) ? 10 : 100 

Низкий приоритет для тройного оператора достигает этой цели. Такого рода вещи являются всей причиной приоритета операторов, которые вы найдете на языках. Цель состоит в том, чтобы было удобно писать выражения, которые, как ожидается, будут нормальными в языке. Правильно? Если нет, это может быть просто слева направо с круглыми скобками. Что будет раздражать, и вы бы быстро предложили какой-то удобный приоритет оператора.

Ответ 4

Верно, что оператор ?: не имеет четко определенного приоритета. Но этот пример на самом деле не иллюстрирует это. Относительные приоритеты << и ?: довольно однозначны. Весь ваш пример показывает, что приоритет << выше приоритета ?:.

Что касается более общей проблемы приоритета оператора ?: operator... ?:, то он имеет относительно запутанный формат по сравнению с другими операторами: он имеет три неравномерных операнда. Из-за этой неравномерности часть до ? имеет разные синтаксические группирующие свойства, чем части после ?.

В конце концов, "приоритеты" - это производный трюк, изобретенный для упрощения визуализации и запоминания синтаксических группировок, определенных грамматикой. Тем не менее, не все операторы на С++. Оператором ?: является тот, который этого не делает, поэтому правильно написанная таблица приоритетов обычно имеет боковое примечание для оператора ?:, объясняя его необычные свойства. Опять же, часть перед ? имеет другой приоритет, чем части после ?, поэтому невозможно правильно помещать оператор ?: в линейную таблицу приоритетов.

Если я что-то забыл, оператор ?: является единственным оператором без однозначно определяемого приоритета.

P.S. Вещи с оператором ?: были еще хуже в C. С++-связанных изменениях в грамматике, сделанной ?:, чтобы лучше соответствовать идее линейного приоритета.

Ответ 5

Как и другие ответы, оператор << имеет более высокий приоритет, чем оператор ?. Вот мое мнение о том, почему это так.

Использование бит-сдвига (<<) с оператором выбора имеет смысл; например

(T == true) ? (whatever << 1) : (whatever << 2)
(T == true) ? whatever << 1 : whatever << 2 // same as above

Когда разработчики С++ изобрели перегрузку оператора, они решили повторно использовать оператор бит-сдвига << в качестве оператора потоковой передачи. Если бы они представили другой, совершенно новый потоковый оператор (например, <<<), он получил бы очень низкий приоритет, поэтому код работал бы так, как ожидалось:

cout <<< (T == true) ? "true" : "false";

Однако введение нового оператора только для его перегрузки может подорвать идею полезности перегрузки оператора, что было тогда увлекательной идеей. Поэтому они решили использовать старый (существующий) оператор.

Ответ 6

Тернарный условный оператор имеет приоритет, за исключением того, что он находится в нижней части списка (значение 15). Только throw и , (запятая) имеют меньший приоритет. См. Эту ссылку для Приоритет оператора С++.

Ответ 7

из-за скобок, вычисляется первая инструкция (T == true), затем приходит оператор сдвига влево и 1, который был оценен ранее, отправляется в cout. позже тернарный оператор оценивает "true", но игнорируется.

в целом, тройной оператор имеет приоритет, но один из самых низких.