Почему этот оператор:
int a = 7, b = 8, c = 0;
c = b>a?a>b?a++:b++:a++?b++:a--;
cout << c;
не равно:
int a = 7, b = 8, c = 0;
c = (b>a?(a>b?a++:b++):a++)?b++:a--;
cout << c;
и равно:
int a = 7, b = 8, c = 0;
c = b>a?(a>b?a++:b++):(a++?b++:a--);
cout << c;
Приведите мне некоторую причину. Почему?
Потому что ? :
ассоциативно справа налево. Это так определено в языке.
Операторы &&
, ||
и ?:
осуществляют управление потоком внутри выражений. ?:
ведет себя как оператор if-else.
c = b>a?a>b?a++:b++:a++?b++:a--;
if ( b>a )
if ( a>b )
a ++;
else
b ++;
else if ( a ++ )
b ++;
else
a --;
b>a? (
a>b ?
a ++
:
b ++
) : ( a ++ ?
b ++
:
a --
)
Ассоциативность необходима для поведения типа if ... else if ... else
.
Иногда я использую выражение, подобное вашему, для сравнения лексикографических последовательностей:
operator< ()( arr &l, arr &r ) {
return l[0] < r[0]? true
: r[0] < l[0]? false
: l[1] < r[1]? true
: r[1] < l[1]? false
: l[2] < r[2];
}
Я считаю, что @sth дал правильный ответ, однако я думаю, что @Skilldrick правильно понял его в комментариях - какого черта ты вообще мог написать что-то подобное.
Помимо проблемы приоритета, вам действительно нужно быть осторожным при увеличении одних и тех же переменных в одном операторе. В операторе могут быть или не быть точки последовательности, и поэтому порядок оценки приращений не может быть гарантирован. Вы можете получить разные результаты с разными компиляторами или даже с разными настройками оптимизации на одном компиляторе.