Порядок приоритета операторов в C++
В следующей таблице перечислены приоритет и ассоциативность операторов C++. Операторы перечислены сверху вниз в порядке убывания приоритета.
- Операнд
sizeofне может быть преобразованием типа в стиле C: выражениеsizeof (int) * pоднозначно интерпретируется как(sizeof(int)) * p, но не какsizeof((int)*p). - Выражение в середине условного оператора (между
?и:) анализируется как будто в скобках: его приоритет относительно?:игнорируется.
При разборе выражения оператор, который находится в какой-либо строке таблицы выше с указанным приоритетом, будет связан с его операндами сильнее (как если бы с помощью скобок), чем любой оператор, который находится в строке ниже с меньшим приоритетом. Например, выражения std::cout << a & b и *p++ разбираются как (std::cout << a) & b и *(p++), а не как std::cout << (a & b) или (*p)++.
Операторы с одинаковым приоритетом связываются со своими операндами в соответствии со своей ассоциативностью. Например, выражение a = b = c разбирается как a = (b = c), а не как (a = b) = c из-за ассоциативности справа налево присваивания, но a + b - c разбирается как (a + b) - c, а не как a + (b - c) из-за ассоциативности слева направо сложения и вычитания.
Указание ассоциативности избыточно для унарных операторов и показано только для полноты: унарные префиксные операторы всегда связываются справа налево (delete ++*p это delete(++(*p))) и унарные постфиксные операторы всегда связываются слева направо (a[1][2]++ это ((a[1])[2])++). Обратите внимание, что ассоциативность имеет смысл для операторов доступа к членам, даже если они сгруппированы с унарными постфиксными операторами: a.b++ разбирается как (a.b)++, а не как a.(b++).
Порядок приоритета операторов не зависит от перегрузки операторов. Например, std::cout << a ? b : c; разбирается как (std::cout << a) ? b : c;, потому что приоритет битового сдвига влево выше, чем условного оператора.
Примечания
Приоритет и ассоциативность — это понятия времени компиляции и независимы от порядка вычисления, которое является понятием времени выполнения.
Сам стандарт не определяет уровни приоритета. Они выводятся из грамматики.
const_cast, static_cast, dynamic_cast, reinterpret_cast, typeid, sizeof..., noexcept и alignof не включены, так как они никогда не являются неоднозначными.
Некоторые операторы имеют альтернативные написания (например, and для &&, or для ||, not для !, и т. д.).
В языке C условный оператор с тремя операндами имеет более высокий приоритет, чем операторы присваивания. Поэтому выражение e = a < d ? a++ : a = d, которое в C++ разбирается как e = ((a < d) ? (a++) : (a = d)), не будет компилироваться в C из-за грамматических или семантических ограничений языка C. Подробности см. на соответствующей странице для C.
См. также
| Общие операторы | ||||||
|---|---|---|---|---|---|---|
| присваивание |
инкремент декремент | арифметические | логические | сравнения |
доступ к членам объекта | прочие |
|
|
|
|
|
|
| вызов функции |
a(...) |
||||||
| запятая | ||||||
a, b |
||||||
| условный | ||||||
a ? b : c |
||||||
| Специальные операторы | ||||||
|
|
||||||
| Документация C по Приоритету операторов C |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/operator_precedence