Почему постфиксный оператор ++ имеет более высокий приоритет, чем префиксный оператор ++? - PullRequest
11 голосов
/ 22 мая 2011

Определенный таким образом, мы не можем сделать ни ++x++, ни ++x--.Но с другой стороны, и (++x)++, и (++x)-- являются полезными выражениями: (++x)++ увеличивает x на два и возвращает значение "посередине", тогда как (++x)-- по существу эквивалентно x+1, но полностьюизбегает необходимости вызывать operator+, что иногда может быть очень полезно.

Так почему же не определено, что приоритет ++x++ автоматически расширяется до (++x)++, а не ++(x++)?Есть ли какой-то скрытый смысл для последнего, который я не понимаю, или это просто чтобы сохранить приоритет простым списком со всеми префиксными операторами, составляющими один единственный уровень?

EDIT OkЯ не сказал это явно, но: конечно, я имел в виду x как определяемый пользователем тип.Для встроенных типов (x+=2)-1, конечно, лучше, чем (++x)++, а x+1 на лот лучше, чем (++x)--.Ситуация, которую я имею в виду, это итератор для довольно сложного типа полуассоциативного контейнера, где операторы += и + (предназначенные для произвольного доступа) должны перестроить кэш, чтобы эффективно работать для общих запросов.и, следовательно, на порядок медленнее, чем ++.Но, конечно, я могу изменить их, чтобы всегда сначала проверять, является ли аргумент очень маленьким целым числом, и в этом случае просто вызывать operator++ несколько раз вместо выполнения процедуры произвольного доступа.Это должно хорошо работать здесь, хотя я мог бы предположить, что в какой-то момент у меня может возникнуть ситуация, в которой я хочу, чтобы operator+= всегда шел по пути произвольного доступа, независимо от того, как малые числа я представляю.


Итак ... для меня я бы заключил, что ответом будет:

преимущество наличия простого и хорошо запоминающегося списка приоритетов, в который входят все постфиксные операторыдо любого префиксных операторов достаточно, чтобы допустить незначительный недостаток, заключающийся в необходимости всегда использовать скобки для составления пре- и постфиксных операторов ++ / --, так как эта композиция используется очень редко.

Более простая "C делает это таким образом", хотя, вероятно, это и есть причина real , для меня гораздо менее удовлетворительна, потому что ++x++ не было разрешено вообще в C было бы возможно переопределить эту самую композицию без повреждения какого-либо существующего кода.

В любом случае, я буду продолжать использовать (++x)--, как это действительно делают скобкине так больно.

Ответы [ 3 ]

6 голосов
/ 22 мая 2011

(++x)++ увеличивает x на два и возвращает значение "в середине"

Почему бы не (x += 2) - 1 или (++x, x++)?Оба, кажется, яснее.Для скаляров оба хорошо определены и в C ++ 03, в отличие от предложенного вами выражения.


(++x)-- по существу эквивалентно x+1, но полностью исключает необходимость вызова operator+, что иногда может быть весьма полезно.

Этопроизвольное утверждение без каких-либо объяснений.Поэтому я собираюсь добавить в пул:

x+1 по сути эквивалентно (++x)--, но полностью избегает необходимости вызывать operator++ и operator--, что иногда может быть полезно.


Так почему же не определено, что приоритет ++ x ++ автоматически расширяется до (++ x) ++, а не ++ (x ++)

Просто чтобы такие загадочные угловые случаи не были ошибкой?Ни за что.Не могли бы вы рассказать man operator для меня?Если вы не можете этого сделать, лучше не пытайтесь написать ++x++ в своем коде.

5 голосов
/ 22 мая 2011

Стандарт C ++ просто сохранил правила C, и, очевидно, они не были исправлены, учитывая перегрузку операторов и идиомы, но еще не были изобретены в еще не изобретенном языке.

Глядя на то, что доступно в D.M. Домашняя страница Ричи , на которой видно, что этот приоритет уже присутствует в B ( Унарные операторы связаны справа налево. Таким образом, -!x++ связан -(!(x++)) в Ссылка пользователя на B ) и я не видел операторов приращения в BCPL.

1 голос
/ 22 мая 2011

Оба (++x)++ и (++x)-- вызывают неопределенное поведение [предполагая, что x является примитивным типом]. Для пользовательского типа сценарий будет отличаться . Однако обычно не рекомендуется использовать такие запутанные выражения в вашем коде.

Что касается приоритета , этот ответ объясняет, почему постинкремент имеет более высокий приоритет, чем преинкремент.

...