TL; DR: Документы Microsoft можно интерпретировать как менее правильные, в зависимости от того, как вы на них смотрите.
Первое, что вы должны понять, это то, что в языке C ++ нет оператора " Приоритет "правила. C ++ имеет грамматику ; именно грамматика определяет, что означает конкретный фрагмент синтаксиса C ++. Именно грамматика C ++ говорит вам, что 5 + 3 * 4
следует считать эквивалентным 5 + (3 * 4)
, а не (5 + 3) * 4
.
Следовательно, любые правила «приоритета оператора», которые вы видите, просто текстовое, понятное человеку объяснение грамматики C ++ вокруг разбора выражения . Таким образом, можно представить, что могут существовать два разных способа описания поведения одной и той же грамматики.
Рассмотрим конкретный c пример throw
против оператора ?:
. На сайте Microsoft говорится, что ?:
имеет более высокий приоритет, чем throw
, а сайт Cppreference говорит, что они имеют такой же приоритет.
Сначала давайте рассмотрим гипотетическое выражение C ++:
throw val ? one : two
По правилам Microsoft, оператор ?:
имеет более высокий приоритет, поэтому будет проанализирован как throw (val ? one : two)
. По правилам Cppreference оба оператора имеют одинаковый приоритет. Однако, поскольку они имеют ассоциативность справа налево, ?:
получает первые метки в подвыражениях. Итак, у нас есть throw (val ? one : two)
.
Итак, оба они решают один и тот же результат.
Но что говорит грамматика C ++? Хорошо, вот соответствующий фрагмент грамматики:
throw-expression:
throw assignment-expression(opt)
assignment-expression:
conditional-expression
logical-or-expression assignment-operator initializer-clause
throw-expression
Это анализируется как выражение броска, которое содержит assignment-expression
, которое содержит conditional-expression
, которое является где наш ?:
лежит. Короче говоря, синтаксический анализатор анализирует его как throw (val ? one : two)
.
Таким образом, обе страницы одинаковы, и обе они верны.
Теперь рассмотрим:
val ? throw one : two
Как это анализируется? Хорошо, что нужно помнить, что ?:
является троичным оператором; в отличие от большинства других, у него есть три условия. То есть сам conditional-expression
не является завершенным , указанным до тех пор, пока не будет проанализирован : <something>
.
Таким образом, приоритет throw
против ?:
в данном случае не имеет значения. throw one
находится внутри троичного оператора, потому что выражение буквально в пределах троичного оператора. Два оператора не конкурируют.
Наконец, как насчет:
val ? one : throw two
Microsoft дает ?:
более высокий приоритет. Согласно документации Microsoft, приоритет «определяет порядок операций в выражениях, которые содержат более одного оператора». Таким образом, ?:
происходит первым.
Но вот в чем дело. throw
само по себе является грамматически допустимым выражением (оно допустимо только для C ++ в пределах предложения catch
, но грамматика везде допустима). Таким образом, val ? one : throw
может быть законным выражением, что, как кажется, говорят правила Microsoft.
Конечно, (val ? one : throw) two
не является законным выражением, потому что () two
не является юридическая грамматика C ++. Таким образом, можно интерпретировать правила Microsoft, чтобы сказать, что это должно быть ошибкой компиляции.
Но это не так. Грамматические состояния C ++:
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
throw two
- это полный assignment-expression
, используемый в качестве третьего операнда данного выражения. Так что это должно быть проанализировано как val ? one : (throw two)
.
А как насчет Cppreference? Что ж, давая им ассоциативность справа налево, throw two
группируется с самим собой. Так что стоит считать val ? one : (throw two)
.