Подтвердить что ты не робот

Unary + по указателям

Я просто просматривал черновик стандарта С++ 11 и нашел следующее озадачивающее утверждение (§13.6/8):

Для каждого типа T существуют возможные операторные функции вида

T* operator+(T*);

Как следует понимать этот "унарный +" оператор на указателе? Это просто нет-op в нормальном случае, который, тем не менее, может быть перегружен? Или есть какая-то более глубокая точка, которую я здесь отсутствует?

4b9b3361

Ответ 1

Ответ на ваш вопрос - это просто страница выше цитаты, которую вы цитировали — §13.6/1:

Функции оператора-кандидата, представляющие встроенные операторы, определенные в разделе 5, указаны в этом подпункте. Эти кандидатские функции участвуют в процессе разрешения перегрузки оператора, как описано в 13.3.1.2, и используются без каких-либо других целей. [Примечание: поскольку встроенные операторы принимают только операнды с неклассовым типом, а оператор разрешение перегрузки происходит только тогда, когда изначально выражение операнда имеет тип класса или перечисления, разрешение перегрузки оператора может разрешаться встроенным оператором только тогда, когда операнд имеет тип класса, который имеет определяемое пользователем преобразование в тип неклассов, подходящий для или когда операнд имеет тип перечисления, который может быть преобразован в тип, подходящий для оператора. Также обратите внимание, что некоторые из функций оператора-кандидата, приведенные в этом подпункте, более разрешительны, чем сами встроенные операторы. Как описано в 13.3.1.2, после того, как встроенный оператор выбирается с помощью разрешения перегрузки, выражение подчиняется требованиям для встроенного оператора, указанному в разделе 5, и, следовательно, к любым дополнительным семантическим ограничениям, данным там. Если имеется пользовательский кандидат с тем же именем и параметрами, что и встроенная функция-оператор-кандидат, встроенная функция оператора скрыта и не включена в набор функций-кандидатов. -end note]

Ответ 2

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

int a[] = { 1, 2, 3 };
auto &&x = +a;

Теперь x является int*&&, а не int(&)[3]. Если вы хотите передать шаблоны x или +a, это различие может стать важным. a + 0 не всегда эквивалентно, рассмотрим

struct forward_decl;
extern forward_decl a[];
auto &&x = +a; // well-formed
auto &&y = a + 0; // ill-formed

Последняя строка плохо сформирована, потому что добавление чего-либо к указателю требует полного указания указателя на тип класса (потому что он продвигается на sizeof(forward_decl) * N bytes).

Ответ 3

Ну, вы можете перегрузить его, делаете все, что хотите, но это просто для симметрии с унарным оператором. Как вы говорите, это просто не-op большую часть времени.