Это просто артефакт того, как ассоциативность выводится из грамматики.
Причина того, что сложение является левоассоциативным, заключается в том, что одним из продуктов для аддитивного-выражения является аддитивное-выражение + мультипликативное-выражение , с аддитивным выражением слева. Итак, когда вы видите:
a + b + c
это должно быть эквивалентно (a + b) + c
, потому что единственный способ сопоставить продукцию — использовать a + b
в качестве аддитивного-выражения и c
в качестве мультипликативного-выражения. a
само по себе является аддитивным-выражением, но b + c
не является мультипликативным-выражением, и поэтому a + b + c
не соответствует произведению, если мы попытаемся взять a
в качестве < em>аддитивное-выражение.
Если вы еще этого не сделали, я рекомендую вам прочитать главу «Выражения», игнорируя семантику: смотрите только на грамматические постановки. Тогда вы увидите, как старшинство и ассоциативность определяются грамматикой. Большой трюк заключается в том, что каждый тип выражения с «высоким приоритетом» ЯВЛЯЕТСЯ типом выражения с «низким приоритетом». Таким образом, каждое мультипликативное-выражение является аддитивным-выражением, но не наоборот, и это то, что делает умножение "более тесным", чем сложение.
Префиксные унарные операторы определены в грамматике следующим образом: унарное-выражение: ++ приведенное-выражение и т. д., с оператором слева для префикса и справа для постфикс. Другими словами, мы «вставляем скобки» слева для постфикса и справа для префикса. То есть мы можем сказать, что группировка осуществляется слева направо для постфиксных операторов и справа налево для префиксных операторов. И действительно, стандарт C++ говорит именно об этом (5.2/1 и 5.3/1 в C++03). Это может быть злоупотреблением терминологией или, по крайней мере, новой чеканкой, чтобы называть эту унарную группировку «ассоциативностью». Но это не главное, так как очевидно, что следует иметь в виду.
Единственная разница между бинарными и унарными операторами заключается в том, что синтаксис все равно имел бы смысл, если бы бинарные операторы группировались в противоположном направлении, поэтому a - b - c
означает a - (b - c)
. Это было бы удивительно, но иначе не повлияло бы на язык. С унарными операторами было бы более чем неожиданно сгруппировать !!a
как (!!)a
, язык также должен был бы предоставить значение для подвыражения !!
, которого в настоящее время у него нет. Функциональный язык мог бы дать ему значение: !!
может означать функцию, состоящую из !
и !
, то есть ту же операцию, что и static_cast<bool>()
, но C++ не имеет концепции составления функций или операторов. Причина, по которой С++ не должен предоставлять это значение, заключается в том, что !
"группирует справа налево". Что (из-за большого трюка в грамматике) является просто еще одним способом сказать, что !!
не является синтаксически правильным выражением, поэтому никогда не является подвыражением чего-либо.
Так что да, имеет смысл сказать, что префиксные операторы группируются справа налево, а постфиксные операторы группируются слева направо. Но также «очевидно», что так и должно быть, потому что мы знаем о языке C++ другие вещи.
Кстати, я думаю, что с технической точки зрения, по крайней мере, в C++, постфикс ++
не унарный оператор. Это постфиксный оператор. Но на самом деле это не имеет значения, за исключением того, что это терминология в стандарте, потому что, очевидно, это оператор и у него один операнд, как и «унарный» в английском языке.
person
Steve Jessop
schedule
18.10.2012