Приоритет оператора - все о разрешении неясностей. Скажем, например, у нас есть два оператора op1
и op2
и следующее выражение:
x = a op1 b op2 c
Мы могли бы решить это логически как
tmp = a op1 b
x = tmp op2 c
Но это также было бы возможно сначала оценить op2
, вот так:
tmp = b op2 c
x = a op1 tmp
Это неоднозначно. Чтобы решить эту двусмысленность, мы могли бы потребовать скобки или дать одному из операторов более высокий приоритет. Это в основном то же самое, что мы используем в математике с выражением типа 1 + 2 * 3
, где умножение имеет более высокий приоритет и должно вычисляться первым.
Ват, что это значит для вашего примера? Как вы уже написали, ||
имеет более высокий приоритет, чем ?:
. Это означает, что
true || false
будет оцениваться первым и всегда приводит к true
. Таким образом, ваша троица фактически становится
true ? false : true
и всегда будет false
.
Как компилятор примет это решение? Давайте (упрощенно) посмотрим на шаги:
- изначально компилятор видит
true
, что уже является значением. - компилятор видит
||
и теперь знает, что там должен следовать за другим значением или оцененным выражением. - тогда компилятор видит
false
. Это может быть значением, но, поскольку оно может быть частью другого выражения, оно еще не сделано. - Затем компилятор встречает
?
, который он идентифицирует как троичный оператор - , поскольку троичный имеет более низкий приоритет, чем
||
, он должен рассматривать все выражение true || false
как первый операнд троичного числа.
Что касается того, почему троичный оператор имеет более низкий приоритет, чем ||
I Можно только предположить, что это для согласованности. Тернар является не только единственным оператором с тремя операндами, но также только второй и третий должны иметь один и тот же тип данных, тогда как первый всегда равен bool
. Более низкий приоритет гарантирует, что эти два назначения семантически одинаковы:
bool b = condition1 || condition2 ? true : false;
int i = condition1 || condition2 ? 23 : 42;