Какие законные причины существуют для перегрузки унарного оператора?

Хорошо, я был вдохновленный сделать перфорирование головы. Кажется, что перегрузка operator& приводит к небольшому количеству боли.

Какие законные случаи существуют для перегрузки?

(Не могу сказать, что я когда-либо делал это....)

Ответ 1

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

Ага, вспомнил: Microsoft CComPtr.

Изменить: Чтобы обобщить, это может иметь смысл при следующих условиях:

  • У вас есть объект, который маскируется как какой-то другой объект.
  • Этот объект может получить указатель на предмет, который он маскирует как.

Возвращение чего-либо другого, кроме законного указателя, нарушит принцип наименьшего удивления.

Ответ 2

Перегрузка унарного & заставляет ваш объект вести себя как ссылка (в этом отношении).

Я уверен, что это безумное поручение попытаться предоставить альтернативы встроенным ссылкам, в частности, поскольку ссылки не являются объектами вообще на С++, и у них нет собственных адресов. Экземпляры вашего пользовательского типа неизбежно являются объектами и имеют адреса, даже если вы отключите обычный способ получения этого адреса. Таким образом, это никогда не идеальное подражание.

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

Ответ 3

Это полезно, когда вы представляете операцию & в нотации замещения lambda, например. &_1[_2].

Ответ 4

Четыре года спустя, другой ответ.

Другое использование, которое я видел, - это когда вы переписываете язык С++, но определяете свою собственную семантику. Пример: Boost.Spirit.

Boost.Spirit, в частности Qi для синтаксического анализа, перегружает операторы на синтаксические анализаторы, чтобы обеспечить синтаксис типа EBNF для указания произвольных объектов парсера. В частности, унарный оператор & перегружен, чтобы обеспечить And-Predicate Parser.

И-Predicate Parser (& a)

Описание

Синтаксические предикаты утверждают определенный условный синтаксис, который необходимо выполнить перед оценкой другого производства. Подобно семантическим предикатам, eps, синтаксические предикаты не потребляют никакого ввода. and-predicate, & a, является положительным синтаксическим предикатом, который возвращает совпадение нулевой длины, только если его предикат соответствует.

Пример использования:

Основной пример внешнего вида: убедитесь, что последний символ является точка с запятой, но не потребляйте ее, просто загляните в следующий символ:

test_phrase_parser("Hello ;", lit("Hello") >> &lit(';'), false);

Итак, унарный & здесь не имеет никакого отношения к указателям; он имеет специфичную для домена семантику, которая применяется к объектам парсеров Qi.

Ответ 5

Я сделал это с хорошим эффектом в контексте DSL, который генерирует код LLVM. Пример иллюстрирует. Скажем x и y являются значениями (т.е. Объектами типа value). Затем выражение x+y выдает инструкцию ADD в некоторый поток кода. Вполне разумно, выражение &x испускает команду, чтобы принять адрес x.

Ответ 6

Как только я использовал переопределить оператор и (без изменения его поведения) как частный для класса, чтобы защитить от случайного создания умного указателя на объект, созданный в стеке. Все еще не уверен, была ли это действительно хорошая идея...

Ответ 7

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