Почему оператор приращения постфикса принимает фиктивный параметр?

Посмотрите на эти сигнатуры функций:

 class Number {
 public:
   Number& operator++ ();    // prefix ++
   Number  operator++ (int); // postfix ++
 }; 

Префикс не принимает никаких параметров, но Postfix делает. Зачем? Я думал, что мы можем распознать их с разными типами возврата.

20
задан Jens Erat 29 May 2013 в 23:00
поделиться

4 ответа

Префикс и постфикс ++ — это разные операторы. Со стандартным объявлением стиля оператора Foo symbol(Foo &) не было очевидного способа различить их.Вместо того, чтобы придумывать какой-то новый синтаксис, такой как Foo symbol operator(Foo &), который превращал бы его в особый случай в отличие от всех других операторов и, вероятно, немного усложнял бы анализ, разработчики языка хотели, чтобы некоторые другое решение.

Решение, которое они выбрали, было несколько странным. Они отметили, что все остальные «постфиксные» операторы (т. е. операторы, стоящие после одного из их операндов) на самом деле были инфиксными операторами, которые принимали два аргумента. Например, старый добрый +, / или >. На этом основании разработчики языка решили, что наличие случайного фиктивного аргумента будет хорошим способом различать префикс и постфикс ++.

ИМХО, это одно из самых странных решений, принятых по мере развития C++. Но вот оно.

И вы не можете отличить их по типу возвращаемого значения по двум причинам.

Во-первых, функции в C++ нельзя перегружать по возвращаемому типу. У вас не может быть двух функций с одинаковыми именами и списками типов параметров, но разными возвращаемыми значениями.

Во-вторых, этот метод не будет достаточно надежным или гибким, чтобы обрабатывать все возможные реализации префикса и постфикса ++.

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

10
ответ дан 30 November 2019 в 00:47
поделиться

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

2
ответ дан 30 November 2019 в 00:47
поделиться

Прямо из уст Бьярна:

Это может быть и слишком мило, и слишком тонко, но оно работает, не требует нового синтаксиса и имеет логику до безумия. Другие унарные операторы являются префиксными и не принимают аргументов, если они определены как функции-члены. «Нечетный» и неиспользуемый фиктивный аргумент int используется для обозначения нечетных постфиксных операторов. Другими словами, в постфиксном случае ++ стоит между первым (действительным) операндом и вторым (фиктивным) аргументом и, таким образом, является постфиксным.

Эти объяснения необходимы, потому что механизм уникален и, следовательно, немного запутан. Если бы у меня был выбор, я бы, вероятно, ввел ключевые слова prefix и postfix, но в то время это казалось невозможным. Однако единственный действительно важный момент заключается в том, что механизм работает и может быть понят и использован теми немногими программистами, которым он действительно нужен.

Кстати, на мой взгляд, только префикс ++ должен перегружаться программистом, а постфикс ++ должен автоматически генерироваться компилятором. Кто со мной согласен?

7
ответ дан 30 November 2019 в 00:47
поделиться

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

OTOH, я не знаю, почему это нельзя было сделать только в синтаксисе:

//prefix
int& ++operator (); 
//postfix
int& operator++ (); 

В конце концов, имитация использования в объявлениях имеет традицию в C и C++.

P.S. Другие постеры: Это не имеет ничего общего с перегрузкой по возвращаемому типу. постфикс и префикс ++/-- это два разных имени. Нет необходимости разрешать перегрузку в x++ или ++x, потому что совершенно ясно, какое имя имеется в виду.

8
ответ дан 30 November 2019 в 00:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: