Почему оператор postfix ++ имеет более высокий приоритет, чем префикс operator ++?
Определенный таким образом, мы не можем сделать ни ++x++
, ни ++x--
. Но с другой стороны, как (++x)++
, так и (++x)--
являются полезными выражениями: (++x)++
увеличивает x
на два и возвращает значение "в середине", а (++x)--
по существу эквивалентно x+1
, но полностью избегает необходимости называть operator+
, что иногда может быть весьма полезным.
Итак, почему приоритет не определен, чтобы ++x++
автоматически расширялся до (++x)++
, а не ++(x++)
? Есть ли какой-то скрытый смысл для последнего, который я не понимаю, или просто сохранить приоритет простым списком со всеми операторами префикса, составляющими один уровень?
EDIT Хорошо, я не сказал этого явно, но: конечно, я имел в виду x
для пользовательского типа. Для встроенных типов (x+=2)-1
, конечно, лучше, чем (++x)++
, а x+1
намного лучше, чем (++x)--
. Ситуация, которую я имею в виду, является итератором для довольно сложного типа полуассоциативного контейнера, где операторы +=
и +
(предназначенные для произвольного доступа) должны перестраивать кеш, чтобы эффективно работать для общих запросов, и, следовательно, на порядок медленнее, чем ++
. Но, конечно, я могу изменить их, чтобы всегда проверять, если аргумент является очень маленьким целым числом, и в этом случае просто вызывать operator++
несколько раз, а не выполнять процедуру произвольного доступа. Это должно сработать хорошо, хотя я мог представить, что в какой-то момент я мог бы иметь ситуацию, в которой я хочу, чтобы operator+=
всегда проходил случайный доступ, независимо от того, как небольшие числа я представляю его.
Итак... для меня, я бы пришел к заключению:
преимущество наличия простого и хорошо запоминаемого списка приоритетов, в котором все операторы постфикса доходят до того, как какой-либо из префиксных операторов достаточно, чтобы терпеть незначительный недостаток, когда всегда приходится использовать круглые скобки для составления пред- и постфиксных операторов ++
/--
, так как эта композиция используется очень редко.
Более простой "C делает это таким образом", хотя он, вероятно, является реальной причиной, гораздо менее удовлетворяет мне, потому что, поскольку ++x++
вообще не разрешалось в C, было бы возможно переопределить этот самый состав, не повреждая какой-либо существующий код.
В любом случае, я продолжу использовать (++x)--
, так как скобки действительно не так больно.
Ответы
Ответ 1
Стандарт С++ просто сохранил правила C, и, очевидно, они не были исправлены, учитывая перегрузку и идиомы операторов, но придуманные еще на языке изобретательности.
Глядя на то, что доступно в D.M. Ritchie Home, см., Что это приоритет уже присутствует в B (унарные операторы привязаны справа налево. Таким образом, -!x++
привязан -(!(x++))
в ссылке на пользователя B), и я не видел приращения операторов в BCPL.
Ответ 2
(++x)++
увеличивает x
на два и возвращает значение "посередине"
Почему бы не (x += 2) - 1
или (++x, x++)
? Оба кажутся более ясными. Для скаляров оба хорошо определены также в С++ 03, в отличие от предлагаемого выражения.
(++x)--
по существу эквивалентен x+1
, но полностью избегает необходимости называть operator+
, что иногда может быть весьма полезным.
Это произвольное утверждение без каких-либо объяснений. Поэтому я собираюсь бросить в пул:
x+1
по существу эквивалентен (++x)--
, но полностью исключает необходимость вызова operator++
и operator--
, которые иногда могут быть полезны.
Итак, почему приоритет не определен, чтобы ++ x ++ автоматически расширялся до (++ x) ++, а не ++ (x ++)
Просто, чтобы сделать такие тайные угловые случаи не ошибками? Ни за что. Вы можете прочесть man operator
для меня? Если вы не можете этого сделать, лучше не пытаться писать ++x++
в свой код.
Ответ 3
Оба (++x)++
и (++x)--
вызывают undefined поведение [предполагая, что x является примитивным типом]. Для пользовательского типа сценарий будет отличаться. Однако обычно не рекомендуется использовать такие запутывающие выражения в вашем коде.
Что касается вопроса о заинтересованности этот ответ, объясняет, почему post increment имеет более высокий приоритет, чем предварительный приращение.